Skip to content

Commit

Permalink
update cairo to 2.10rc-0 (#986)
Browse files Browse the repository at this point in the history
* update cairo to 2.10rc-0 and the vm

* cairo-vm 2.0.0rc3, implement redeposit_gas (not finished)

* implement redeposit_gas libfunc and ignore alexandria temporarily

* remove ignore alexandria

* remove ignore alexandria

* remove ignore alexandria

* add tests

* Fix `bounded_int_trim` libfunc implementation.

* remove unwanted files

* clippy

* clippy

* fix test

* document new libfuncs

* document new libfuncs

* fix typo

* Fix `bounded_int_trim` for signed types.

* Remove unnecessary `if` expression.

* prepare for release

* handle positive signed values

* document 'is_signed' method

* typo

* document better redeposit gas

* better check in bounded int trim

---------

Co-authored-by: Esteve Soler Arderiu <[email protected]>
  • Loading branch information
FrancoGiachetta and azteca1998 authored Jan 3, 2025
1 parent 448f0d4 commit 1b3e7c1
Show file tree
Hide file tree
Showing 13 changed files with 487 additions and 286 deletions.
430 changes: 183 additions & 247 deletions Cargo.lock

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cairo-native"
version = "0.2.5"
version = "0.2.5-rc2"
edition = "2021"
license = "Apache-2.0"
description = "A compiler to convert Cairo's intermediate representation Sierra code to MLIR."
Expand Down Expand Up @@ -58,13 +58,13 @@ normal = ["aquamarine"]
[dependencies]
aquamarine = "0.5.0"
bumpalo = "3.16.0"
cairo-lang-compiler = "2.9.2"
cairo-lang-defs = "2.9.2"
cairo-lang-filesystem = "2.9.2"
cairo-lang-runner = "2.9.2"
cairo-lang-semantic = "2.9.2"
cairo-lang-sierra = "2.9.2"
cairo-lang-sierra-generator = "2.9.2"
cairo-lang-compiler = "2.10.0-rc.0"
cairo-lang-defs = "2.10.0-rc.0"
cairo-lang-filesystem = "2.10.0-rc.0"
cairo-lang-runner = "2.10.0-rc.0"
cairo-lang-semantic = "2.10.0-rc.0"
cairo-lang-sierra = "2.10.0-rc.0"
cairo-lang-sierra-generator = "2.10.0-rc.0"
educe = "0.5.11" # can't update until https://github.com/magiclen/educe/issues/27
itertools = "0.13.0"
lazy_static = "1.5"
Expand All @@ -86,12 +86,12 @@ utf8_iter = "1.0.4"


# CLI dependencies
cairo-lang-sierra-ap-change = "2.9.2"
cairo-lang-sierra-gas = "2.9.2"
cairo-lang-starknet = "2.9.2"
cairo-lang-utils = "2.9.2"
cairo-lang-starknet-classes = "2.9.2"
cairo-native-runtime = { version = "0.2.5", path = "runtime", optional = true }
cairo-lang-sierra-ap-change = "2.10.0-rc.0"
cairo-lang-sierra-gas = "2.10.0-rc.0"
cairo-lang-starknet = "2.10.0-rc.0"
cairo-lang-utils = "2.10.0-rc.0"
cairo-lang-starknet-classes = "2.10.0-rc.0"
cairo-native-runtime = { version = "0.2.5-rc2", path = "runtime", optional = true }
clap = { version = "4.5.23", features = ["derive"], optional = true }
libloading = "0.8.6"
tracing-subscriber = { version = "0.3.19", features = [
Expand All @@ -101,7 +101,7 @@ tracing-subscriber = { version = "0.3.19", features = [
], optional = true }
serde = { version = "1.0", features = ["derive"] }
anyhow = { version = "1.0", optional = true }
cairo-lang-test-plugin = { version = "2.9.2", optional = true }
cairo-lang-test-plugin = { version = "2.10.0-rc.0", optional = true }
colored = { version = "2.1.0", optional = true }
# needed to interface with cairo-lang-*
keccak = "0.1.5"
Expand All @@ -119,8 +119,8 @@ ark-ff = "0.5.0"
num-integer = "0.1.46"

[dev-dependencies]
cairo-vm = { version = "2.0.0-rc0", features = ["cairo-1-hints"] }
cairo-lang-semantic = { version = "2.9.2", features = ["testing"] }
cairo-vm = { version = "2.0.0-rc3", features = ["cairo-1-hints"] }
cairo-lang-semantic = { version = "2.10.0-rc.0", features = ["testing"] }
criterion = { version = "0.5.1", features = ["html_reports"] }
lambdaworks-math = "0.11.0"
pretty_assertions_sorted = "1.2.3"
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Environment detection.

UNAME := $(shell uname)
CAIRO_2_VERSION = 2.9.2
CAIRO_2_VERSION = 2.10.0-rc.0
SCARB_VERSION = 2.9.2

# Usage is the default target for newcomers running `make`.
Expand Down
4 changes: 2 additions & 2 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cairo-native-runtime"
version = "0.2.5"
version = "0.2.5-rc2"
description = "The runtime for cairo-native."
edition = "2021"
license = "Apache-2.0"
Expand All @@ -15,7 +15,7 @@ starknet-types-core = { version = "0.1.7", default-features = false, features =
"serde",
"hash",
] }
cairo-lang-sierra-gas = "2.9.2"
cairo-lang-sierra-gas = "2.10.0-rc.0"
starknet-curve = "0.5.1"
lazy_static = "1.5.0"
rand = "0.8.5"
Expand Down
1 change: 1 addition & 0 deletions src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ pub const fn libfunc_to_name(value: &CoreConcreteLibfunc) -> &'static str {
BoundedIntConcreteLibfunc::Constrain(_) => "bounded_int_constrain",
BoundedIntConcreteLibfunc::IsZero(_) => "bounded_int_is_zero",
BoundedIntConcreteLibfunc::WrapNonZero(_) => "bounded_int_wrap_non_zero",
BoundedIntConcreteLibfunc::Trim(_) => "bounded_int_trim",
},
CoreConcreteLibfunc::IntRange(selector) => match selector {
IntRangeConcreteLibfunc::TryNew(_) => "int_range_try_new",
Expand Down
4 changes: 1 addition & 3 deletions src/executor/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,6 @@ mod tests {
&mut StubSyscallHandler::default(),
)
.unwrap();

assert_eq!(result.return_values, vec![Felt::from(n), Felt::from(n * 2)]);
assert_eq!(result.remaining_gas, 18446744073709551615);
});
Expand Down Expand Up @@ -811,9 +810,8 @@ mod tests {
&mut StubSyscallHandler::default(),
)
.unwrap();

assert_eq!(result.return_values, vec![Felt::from(3628800)]);
assert_eq!(result.remaining_gas, 18446744073709538915);
assert_eq!(result.remaining_gas, 18446744073709537615);
}

#[rstest]
Expand Down
189 changes: 188 additions & 1 deletion src/libfuncs/bounded_int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use cairo_lang_sierra::{
extensions::{
bounded_int::{
BoundedIntConcreteLibfunc, BoundedIntConstrainConcreteLibfunc,
BoundedIntDivRemConcreteLibfunc,
BoundedIntDivRemConcreteLibfunc, BoundedIntTrimConcreteLibfunc,
},
core::{CoreLibfunc, CoreType},
lib_func::SignatureOnlyConcreteLibfunc,
Expand Down Expand Up @@ -57,6 +57,9 @@ pub fn build<'ctx, 'this>(
BoundedIntConcreteLibfunc::Constrain(info) => {
build_constrain(context, registry, entry, location, helper, metadata, info)
}
BoundedIntConcreteLibfunc::Trim(info) => {
build_trim(context, registry, entry, location, helper, metadata, info)
}
BoundedIntConcreteLibfunc::IsZero(info) => {
build_is_zero(context, registry, entry, location, helper, metadata, info)
}
Expand Down Expand Up @@ -699,6 +702,56 @@ fn build_constrain<'ctx, 'this>(
Ok(())
}

/// Makes a downcast of a type `T` to `BoundedInt<T::MIN, T::MAX - 1>`
/// or `BoundedInt<T::MIN + 1, T::MAX>` where `T` can be any type of signed
/// or unsigned integer.
///
/// ```cairo
/// extern fn bounded_int_trim<T, const TRIMMED_VALUE: felt252, impl H: TrimHelper<T, TRIMMED_VALUE>>(
/// value: T,
/// ) -> core::internal::OptionRev<H::Target> nopanic;
/// ```
fn build_trim<'ctx, 'this>(
context: &'ctx Context,
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
entry: &'this Block<'ctx>,
location: Location<'ctx>,
helper: &LibfuncHelper<'ctx, 'this>,
_metadata: &mut MetadataStorage,
info: &BoundedIntTrimConcreteLibfunc,
) -> Result<()> {
let value: Value = entry.arg(0)?;
let trimmed_value = entry.const_int_from_type(
context,
location,
info.trimmed_value.clone(),
value.r#type(),
)?;
let trim_type = registry.get_type(&info.param_signatures()[0].ty)?;
let is_invalid = entry.cmpi(context, CmpiPredicate::Eq, value, trimmed_value, location)?;
let int_range = trim_type.integer_range(registry)?;

// There is no need to truncate the value type since we're only receiving power-of-two integers
// and constraining their range a single value from either the lower or upper limit. However,
// since we're returning a `BoundedInt` we need to offset its internal representation
// accordingly.
let value = if info.trimmed_value == BigInt::ZERO || int_range.lower < BigInt::ZERO {
let offset = entry.const_int_from_type(
context,
location,
&info.trimmed_value + 1,
value.r#type(),
)?;
entry.append_op_result(arith::subi(value, offset, location))?
} else {
value
};

entry.append_operation(helper.cond_br(context, is_invalid, [0, 1], [&[], &[value]], location));

Ok(())
}

/// Generate MLIR operations for the `bounded_int_is_zero` libfunc.
fn build_is_zero<'ctx, 'this>(
context: &'ctx Context,
Expand Down Expand Up @@ -761,3 +814,137 @@ fn build_wrap_non_zero<'ctx, 'this>(
&info.signature.param_signatures,
)
}

#[cfg(test)]
mod test {
use cairo_vm::Felt252;

use crate::{
context::NativeContext, execution_result::ExecutionResult, executor::JitNativeExecutor,
utils::test::load_cairo, OptLevel, Value,
};

#[test]
fn test_trim_some_pos_i8() {
let (_, program) = load_cairo!(
use core::internal::{OptionRev, bounded_int::BoundedInt};
use core::internal::bounded_int;
fn main() -> BoundedInt<-128, 126> {
let num = match bounded_int::trim::<i8, 0x7f>(1) {
OptionRev::Some(n) => n,
OptionRev::None => 0,
};

num
}
);
let ctx = NativeContext::new();
let module = ctx.compile(&program, false, None).unwrap();
let executor = JitNativeExecutor::from_native_module(module, OptLevel::Default).unwrap();
let ExecutionResult {
remaining_gas: _,
return_value,
builtin_stats: _,
} = executor
.invoke_dynamic(&program.funcs[0].id, &[], None)
.unwrap();

let Value::BoundedInt { value, range: _ } = return_value else {
panic!();
};
assert_eq!(value, Felt252::from(1_u8));
}

#[test]
fn test_trim_some_neg_i8() {
let (_, program) = load_cairo!(
use core::internal::{OptionRev, bounded_int::BoundedInt};
use core::internal::bounded_int;
fn main() -> BoundedInt<-127, 127> {
let num = match bounded_int::trim::<i8, -0x80>(1) {
OptionRev::Some(n) => n,
OptionRev::None => 1,
};

num
}
);
let ctx = NativeContext::new();
let module = ctx.compile(&program, false, None).unwrap();
let executor = JitNativeExecutor::from_native_module(module, OptLevel::Default).unwrap();
let ExecutionResult {
remaining_gas: _,
return_value,
builtin_stats: _,
} = executor
.invoke_dynamic(&program.funcs[0].id, &[], None)
.unwrap();

let Value::BoundedInt { value, range: _ } = return_value else {
panic!();
};
assert_eq!(value, Felt252::from(1_u8));
}

#[test]
fn test_trim_some_u32() {
let (_, program) = load_cairo!(
use core::internal::{OptionRev, bounded_int::BoundedInt};
use core::internal::bounded_int;
fn main() -> BoundedInt<0, 4294967294> {
let num = match bounded_int::trim::<u32, 0xffffffff>(0xfffffffe) {
OptionRev::Some(n) => n,
OptionRev::None => 0,
};

num
}
);
let ctx = NativeContext::new();
let module = ctx.compile(&program, false, None).unwrap();
let executor = JitNativeExecutor::from_native_module(module, OptLevel::Default).unwrap();
let ExecutionResult {
remaining_gas: _,
return_value,
builtin_stats: _,
} = executor
.invoke_dynamic(&program.funcs[0].id, &[], None)
.unwrap();

let Value::BoundedInt { value, range: _ } = return_value else {
panic!();
};
assert_eq!(value, Felt252::from(0xfffffffe_u32));
}

#[test]
fn test_trim_none() {
let (_, program) = load_cairo!(
use core::internal::{OptionRev, bounded_int::BoundedInt};
use core::internal::bounded_int;
fn main() -> BoundedInt<-32767, 32767> {
let num = match bounded_int::trim::<i16, -0x8000>(-0x8000) {
OptionRev::Some(n) => n,
OptionRev::None => 0,
};

num
}
);
let ctx = NativeContext::new();
let module = ctx.compile(&program, false, None).unwrap();
let executor = JitNativeExecutor::from_native_module(module, OptLevel::Default).unwrap();
let ExecutionResult {
remaining_gas: _,
return_value,
builtin_stats: _,
} = executor
.invoke_dynamic(&program.funcs[0].id, &[], None)
.unwrap();

let Value::BoundedInt { value, range: _ } = return_value else {
panic!();
};
assert_eq!(value, Felt252::from(0));
}
}
Loading

0 comments on commit 1b3e7c1

Please sign in to comment.