Skip to content

refactor: move the Cairo 1 hint processor into its own crate - #2390

Draft
orizi wants to merge 1 commit into
mainfrom
orizi/09-01-refactor_move_the_cairo_1_hint_processor_into_its_own_crate
Draft

refactor: move the Cairo 1 hint processor into its own crate#2390
orizi wants to merge 1 commit into
mainfrom
orizi/09-01-refactor_move_the_cairo_1_hint_processor_into_its_own_crate

Conversation

@orizi

@orizi orizi commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

What

cairo-vm depended on cairo-lang-casm and cairo-lang-starknet-classes behind the cairo-1-hints feature, which pulled the whole Cairo 1 compiler into the dependency tree of anyone who only wanted to run Cairo 0 programs.

Executing Cairo 1 hints means speaking the compiler's Hint AST, so rather than copying those definitions into cairo-vm, the hint processor moves into a new cairo1-hint-processor crate that owns the compiler dependency. Git tracked the four files as renames (93–99% similarity), so the diff reads as a move rather than a rewrite.

cairo-vm is now free of cairo-lang-* in every dependency kind, including dev, and the cairo-1-hints feature is gone rather than merely emptied:

$ cargo tree -p cairo-vm --all-features -e normal,build,dev | grep -c cairo-lang
0

$ cargo check -p cairo-vm --features cairo-1-hints
error: the package 'cairo-vm' does not contain this feature: cairo-1-hints

The ,dev matters: it's what catches a dev-dependency cycle, which is what you'd get by leaving the Cairo 1 tests in vm and pointing them at the new crate. Those 55 tests moved into the new crate instead.

Breaking changes

  • The cairo-1-hints feature of cairo-vm is removed. Depend on cairo1-hint-processor instead. Its extensive_hints feature forwards to cairo-vm/extensive_hints.
  • cairo_vm::hint_processor::cairo_1_hint_processor::*cairo1_hint_processor::*.
  • impl TryFrom<CasmContractClass> for Program is replaced by the free function cairo1_hint_processor::program_from_casm_contract_class. It could not remain a TryFrom impl because both types are foreign to the new crate. Nothing outside cairo-vm's own tests called it, so the impl and its only callers moved together and nothing is stranded.

Per the CHANGELOG's version guide, 3.x (main) is the branch for "new features with breaking API changes", so hard removal is in-policy.

Notes for review

  • No new public surface on cairo-vm. I expected to have to widen some pub(crate) items for the move. The only gap was the moved tests reading the private CairoRunner::program field; get_program() and Program::data_len() already existed, so those are used instead.
  • cairo1-run needed only an import swap (two lines plus one manifest line). It already produced cairo_lang_casm::hints::Hint and the hint processor still consumes exactly that type, so there is no conversion layer anywhere.
  • extensive_hints forwarding is load-bearing. There is a #[cfg(feature = "extensive_hints")] inside dict_manager.rs; after the move it resolves against the new crate's features, so without the forwarding feature it would have silently evaluated to false with no error or warning.
  • cairo1-hint-processor is a new publishable crate and will need publishing alongside cairo-vm.

Verification

  • cargo test -p cairo1-hint-processor -p cairo1-run55 + 35 + 134 passed, 0 failed.
  • cargo clippy clean on all three touched crates; cargo machete clean; cargo build --workspace clean.
  • cargo test -p cairo-vm was not run: its test modules include_bytes! generated Cairo 0 JSON fixtures that need the Python cairo-lang toolchain, which isn't available in my environment. This is pre-existing and unrelated to the diff, but flagging it rather than implying full coverage — CI covers it.

Also updated: the cargo all-features CI matrix (adds the new crate), the nextest feature list and three Makefile targets (all of which passed cairo-1-hints and would now hard-fail), CHANGELOG.md, and docs/onboarding.md. Dropped the dead cairo-lang-runner workspace dependency while in Cargo.toml.

🤖 Generated with Claude Code


This change is Reviewable

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
**Hyper Thereading Benchmark results**




hyperfine -r 2 -n "hyper_threading_main threads: 1" 'RAYON_NUM_THREADS=1 ./hyper_threading_main' -n "hyper_threading_pr threads: 1" 'RAYON_NUM_THREADS=1 ./hyper_threading_pr'
Benchmark 1: hyper_threading_main threads: 1
  Time (mean ± σ):     22.620 s ±  0.032 s    [User: 22.026 s, System: 0.591 s]
  Range (min … max):   22.597 s … 22.643 s    2 runs
 
Benchmark 2: hyper_threading_pr threads: 1
  Time (mean ± σ):     22.630 s ±  0.073 s    [User: 22.043 s, System: 0.583 s]
  Range (min … max):   22.578 s … 22.681 s    2 runs
 
Summary
  hyper_threading_main threads: 1 ran
    1.00 ± 0.00 times faster than hyper_threading_pr threads: 1




hyperfine -r 2 -n "hyper_threading_main threads: 2" 'RAYON_NUM_THREADS=2 ./hyper_threading_main' -n "hyper_threading_pr threads: 2" 'RAYON_NUM_THREADS=2 ./hyper_threading_pr'
Benchmark 1: hyper_threading_main threads: 2
  Time (mean ± σ):     12.161 s ±  0.045 s    [User: 22.125 s, System: 0.602 s]
  Range (min … max):   12.129 s … 12.194 s    2 runs
 
Benchmark 2: hyper_threading_pr threads: 2
  Time (mean ± σ):     12.164 s ±  0.057 s    [User: 22.299 s, System: 0.578 s]
  Range (min … max):   12.124 s … 12.204 s    2 runs
 
Summary
  hyper_threading_main threads: 2 ran
    1.00 ± 0.01 times faster than hyper_threading_pr threads: 2




hyperfine -r 2 -n "hyper_threading_main threads: 4" 'RAYON_NUM_THREADS=4 ./hyper_threading_main' -n "hyper_threading_pr threads: 4" 'RAYON_NUM_THREADS=4 ./hyper_threading_pr'
Benchmark 1: hyper_threading_main threads: 4
  Time (mean ± σ):      9.749 s ±  0.227 s    [User: 35.557 s, System: 0.761 s]
  Range (min … max):    9.588 s …  9.909 s    2 runs
 
Benchmark 2: hyper_threading_pr threads: 4
  Time (mean ± σ):      9.575 s ±  0.163 s    [User: 35.240 s, System: 0.721 s]
  Range (min … max):    9.460 s …  9.691 s    2 runs
 
Summary
  hyper_threading_pr threads: 4 ran
    1.02 ± 0.03 times faster than hyper_threading_main threads: 4




hyperfine -r 2 -n "hyper_threading_main threads: 6" 'RAYON_NUM_THREADS=6 ./hyper_threading_main' -n "hyper_threading_pr threads: 6" 'RAYON_NUM_THREADS=6 ./hyper_threading_pr'
Benchmark 1: hyper_threading_main threads: 6
  Time (mean ± σ):      9.763 s ±  0.382 s    [User: 35.688 s, System: 0.759 s]
  Range (min … max):    9.493 s … 10.033 s    2 runs
 
Benchmark 2: hyper_threading_pr threads: 6
  Time (mean ± σ):      9.720 s ±  0.149 s    [User: 35.200 s, System: 0.727 s]
  Range (min … max):    9.615 s …  9.825 s    2 runs
 
Summary
  hyper_threading_pr threads: 6 ran
    1.00 ± 0.04 times faster than hyper_threading_main threads: 6




hyperfine -r 2 -n "hyper_threading_main threads: 8" 'RAYON_NUM_THREADS=8 ./hyper_threading_main' -n "hyper_threading_pr threads: 8" 'RAYON_NUM_THREADS=8 ./hyper_threading_pr'
Benchmark 1: hyper_threading_main threads: 8
  Time (mean ± σ):      9.775 s ±  0.187 s    [User: 35.456 s, System: 0.796 s]
  Range (min … max):    9.643 s …  9.907 s    2 runs
 
Benchmark 2: hyper_threading_pr threads: 8
  Time (mean ± σ):      9.544 s ±  0.129 s    [User: 35.817 s, System: 0.757 s]
  Range (min … max):    9.453 s …  9.635 s    2 runs
 
Summary
  hyper_threading_pr threads: 8 ran
    1.02 ± 0.02 times faster than hyper_threading_main threads: 8




hyperfine -r 2 -n "hyper_threading_main threads: 16" 'RAYON_NUM_THREADS=16 ./hyper_threading_main' -n "hyper_threading_pr threads: 16" 'RAYON_NUM_THREADS=16 ./hyper_threading_pr'
Benchmark 1: hyper_threading_main threads: 16
  Time (mean ± σ):      9.519 s ±  0.075 s    [User: 36.173 s, System: 0.821 s]
  Range (min … max):    9.465 s …  9.572 s    2 runs
 
Benchmark 2: hyper_threading_pr threads: 16
  Time (mean ± σ):      9.612 s ±  0.151 s    [User: 36.235 s, System: 0.814 s]
  Range (min … max):    9.505 s …  9.719 s    2 runs
 
Summary
  hyper_threading_main threads: 16 ran
    1.01 ± 0.02 times faster than hyper_threading_pr threads: 16


@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Benchmark Results for unmodified programs 🚀

Command Mean [s] Min [s] Max [s] Relative
base big_factorial 2.303 ± 0.019 2.281 2.342 1.00 ± 0.01
head big_factorial 2.300 ± 0.021 2.277 2.335 1.00
Command Mean [s] Min [s] Max [s] Relative
base big_fibonacci 2.186 ± 0.012 2.170 2.209 1.00 ± 0.01
head big_fibonacci 2.185 ± 0.017 2.170 2.222 1.00
Command Mean [s] Min [s] Max [s] Relative
base blake2s_integration_benchmark 7.187 ± 0.158 7.084 7.622 1.01 ± 0.02
head blake2s_integration_benchmark 7.144 ± 0.081 7.090 7.363 1.00
Command Mean [s] Min [s] Max [s] Relative
base compare_arrays_200000 2.317 ± 0.009 2.304 2.332 1.00 ± 0.02
head compare_arrays_200000 2.309 ± 0.034 2.268 2.373 1.00
Command Mean [s] Min [s] Max [s] Relative
base dict_integration_benchmark 1.534 ± 0.009 1.525 1.548 1.00 ± 0.01
head dict_integration_benchmark 1.533 ± 0.006 1.525 1.540 1.00
Command Mean [s] Min [s] Max [s] Relative
base field_arithmetic_get_square_benchmark 1.174 ± 0.004 1.167 1.179 1.00 ± 0.01
head field_arithmetic_get_square_benchmark 1.172 ± 0.005 1.165 1.179 1.00
Command Mean [s] Min [s] Max [s] Relative
base integration_builtins 7.226 ± 0.137 7.139 7.602 1.01 ± 0.03
head integration_builtins 7.149 ± 0.160 7.053 7.578 1.00
Command Mean [s] Min [s] Max [s] Relative
base keccak_integration_benchmark 7.331 ± 0.062 7.259 7.448 1.00 ± 0.02
head keccak_integration_benchmark 7.329 ± 0.102 7.205 7.532 1.00
Command Mean [s] Min [s] Max [s] Relative
base linear_search 2.327 ± 0.011 2.310 2.352 1.00
head linear_search 2.327 ± 0.009 2.315 2.344 1.00 ± 0.01
Command Mean [s] Min [s] Max [s] Relative
base math_cmp_and_pow_integration_benchmark 1.690 ± 0.005 1.684 1.701 1.00
head math_cmp_and_pow_integration_benchmark 1.693 ± 0.017 1.678 1.738 1.00 ± 0.01
Command Mean [s] Min [s] Max [s] Relative
base math_integration_benchmark 1.579 ± 0.007 1.572 1.593 1.00
head math_integration_benchmark 1.580 ± 0.008 1.569 1.593 1.00 ± 0.01
Command Mean [s] Min [s] Max [s] Relative
base memory_integration_benchmark 1.328 ± 0.007 1.320 1.343 1.00
head memory_integration_benchmark 1.329 ± 0.013 1.315 1.355 1.00 ± 0.01
Command Mean [s] Min [s] Max [s] Relative
base operations_with_data_structures_benchmarks 1.628 ± 0.008 1.617 1.640 1.00
head operations_with_data_structures_benchmarks 1.634 ± 0.030 1.618 1.719 1.00 ± 0.02
Command Mean [ms] Min [ms] Max [ms] Relative
base pedersen 519.5 ± 2.7 516.2 524.2 1.00 ± 0.01
head pedersen 519.3 ± 1.5 516.6 521.8 1.00
Command Mean [ms] Min [ms] Max [ms] Relative
base poseidon_integration_benchmark 660.1 ± 2.7 655.5 663.5 1.00 ± 0.00
head poseidon_integration_benchmark 659.0 ± 1.9 655.5 662.6 1.00
Command Mean [s] Min [s] Max [s] Relative
base secp_integration_benchmark 1.756 ± 0.010 1.745 1.777 1.00 ± 0.01
head secp_integration_benchmark 1.752 ± 0.006 1.744 1.762 1.00
Command Mean [ms] Min [ms] Max [ms] Relative
base set_integration_benchmark 683.2 ± 2.2 679.3 686.9 1.01 ± 0.01
head set_integration_benchmark 679.2 ± 3.8 673.5 687.7 1.00
Command Mean [s] Min [s] Max [s] Relative
base uint256_integration_benchmark 4.221 ± 0.056 4.189 4.371 1.00
head uint256_integration_benchmark 4.270 ± 0.018 4.251 4.301 1.01 ± 0.01

@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.21%. Comparing base (eeebcc9) to head (2668732).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2390   +/-   ##
=======================================
  Coverage   96.21%   96.21%           
=======================================
  Files         107      108    +1     
  Lines       37925    37927    +2     
=======================================
+ Hits        36490    36492    +2     
  Misses       1435     1435           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TomerStarkware TomerStarkware left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@TomerStarkware partially reviewed 23 files and all commit messages, and made 1 comment.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on eytan-starkware, orizi, and yuvalsw).


cairo1-hint-processor/src/program.rs line 18 at r1 (raw file):

///
/// This is a free function rather than a `TryFrom` impl because both types are foreign to this
/// crate.

remove

Code quote:

/// This is a free function rather than a `TryFrom` impl because both types are foreign to this
/// crate.

The cairo-vm library depended on cairo-lang-casm and cairo-lang-starknet-classes
behind the cairo-1-hints feature, which pulled the whole Cairo 1 compiler into
the dependency tree of anyone who only wanted to run Cairo 0 programs.

Executing Cairo 1 hints means speaking the compiler's Hint AST, so rather than
copying those definitions into cairo-vm, the hint processor moves to a new
cairo1-hint-processor crate that owns the compiler dependency. cairo-vm is now
free of cairo-lang-* in every dependency kind, including dev, and the
cairo-1-hints feature is gone rather than merely emptied.

The move needed no new public surface on cairo-vm: the tests that came along
switched from the private CairoRunner::program field to the existing
get_program()/data_len() accessors.

TryFrom<CasmContractClass> for Program could not come along as an impl, since
both types are foreign to the new crate; it is now the free function
program_from_casm_contract_class. Nothing outside cairo-vm's own tests called
it, so nothing is stranded.

cairo1-run needed only an import swap - it already produced
cairo_lang_casm::hints::Hint and the hint processor still consumes exactly that
type, so no conversion layer exists anywhere.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@orizi
orizi force-pushed the orizi/09-01-refactor_move_the_cairo_1_hint_processor_into_its_own_crate branch from 9ea5588 to 2668732 Compare September 2, 2026 09:35

@orizi orizi left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@orizi made 1 comment.
Reviewable status: 22 of 23 files reviewed, 1 unresolved discussion (waiting on eytan-starkware, TomerStarkware, and yuvalsw).


cairo1-hint-processor/src/program.rs line 18 at r1 (raw file):

Previously, TomerStarkware wrote…

remove

Done.

@TomerStarkware TomerStarkware left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@TomerStarkware reviewed 1 file.
Reviewable status: all files reviewed (commit messages unreviewed), 1 unresolved discussion (waiting on eytan-starkware and yuvalsw).

@TomerStarkware TomerStarkware left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

:lgtm:

@TomerStarkware made 1 comment and resolved 1 discussion.
Reviewable status: all files reviewed (commit messages unreviewed), all discussions resolved (waiting on eytan-starkware and yuvalsw).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants