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

update cairo to 2.10rc-0 #986

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
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
426 changes: 181 additions & 245 deletions Cargo.lock

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
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,11 +86,11 @@ 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-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", path = "runtime", optional = true }
clap = { version = "4.5.23", features = ["derive"], optional = true }
libloading = "0.8.6"
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
2 changes: 1 addition & 1 deletion runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 @@ -737,7 +737,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 @@ -807,9 +806,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
143 changes: 142 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,41 @@ fn build_constrain<'ctx, 'this>(
Ok(())
}

/// Generate MLIR operations for the `bounded_int_trim` libfunc.
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<()> {
JulianGCalderon marked this conversation as resolved.
Show resolved Hide resolved
let value: Value = entry.arg(0)?;
let trimmed_value = entry.const_int_from_type(
context,
location,
info.trimmed_value.clone(),
value.r#type(),
)?;

let is_invalid = entry.cmpi(context, CmpiPredicate::Eq, value, trimmed_value, location)?;

// 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 {
let k1 = entry.const_int_from_type(context, location, 1, value.r#type())?;
entry.append_op_result(arith::subi(value, k1, 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 +799,106 @@ 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_u8() {
let (_, program) = load_cairo!(
use core::internal::{OptionRev, bounded_int::BoundedInt};
use core::internal::bounded_int;
fn main() -> BoundedInt<1, 255> {
let num = match bounded_int::trim::<u8, 0>(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));
}
}
80 changes: 77 additions & 3 deletions src/libfuncs/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ pub fn build<'ctx, 'this>(
GasConcreteLibfunc::WithdrawGas(info) => {
build_withdraw_gas(context, registry, entry, location, helper, metadata, info)
}
GasConcreteLibfunc::RedepositGas(_) => todo!("implement redeposit gas libfunc"),
GasConcreteLibfunc::RedepositGas(info) => {
build_redeposit_gas(context, registry, entry, location, helper, metadata, info)
}
GasConcreteLibfunc::GetAvailableGas(info) => {
build_get_available_gas(context, registry, entry, location, helper, metadata, info)
}
Expand Down Expand Up @@ -80,7 +82,7 @@ pub fn build_withdraw_gas<'ctx, 'this>(

let gas_cost = metadata
.get::<GasCost>()
.expect("builtin_withdraw_gas should always have a gas cost")
.expect("withdraw_gas should always have a gas cost")
.clone();

let u64_type: melior::ir::Type = IntegerType::new(context, 64).into();
Expand Down Expand Up @@ -153,6 +155,78 @@ pub fn build_withdraw_gas<'ctx, 'this>(
Ok(())
}

pub fn build_redeposit_gas<'ctx, 'this>(
context: &'ctx Context,
_registry: &ProgramRegistry<CoreType, CoreLibfunc>,
entry: &'this Block<'ctx>,
location: Location<'ctx>,
helper: &LibfuncHelper<'ctx, 'this>,
metadata: &mut MetadataStorage,
_info: &SignatureOnlyConcreteLibfunc,
) -> Result<()> {
JulianGCalderon marked this conversation as resolved.
Show resolved Hide resolved
let current_gas = entry.arg(0)?;

let gas_cost = metadata
.get::<GasCost>()
.expect("redeposit_gas should always have a gas cost")
.clone();

let u64_type: melior::ir::Type = IntegerType::new(context, 64).into();

let builtin_ptr = {
let runtime = metadata
.get_mut::<RuntimeBindingsMeta>()
.ok_or(Error::MissingMetadata)?;
runtime
.get_gas_builtin(context, helper, entry, location)?
.result(0)?
.into()
};

let mut total_gas_cost_value = entry.const_int_from_type(context, location, 0, u64_type)?;

for (cost_count, token_type) in &gas_cost.0 {
if *cost_count == 0 {
continue;
}

let builtin_costs_index = match token_type {
CostTokenType::Const => 0,
CostTokenType::Pedersen => 1,
CostTokenType::Bitwise => 2,
CostTokenType::EcOp => 3,
CostTokenType::Poseidon => 4,
CostTokenType::AddMod => 5,
CostTokenType::MulMod => 6,
_ => native_panic!("matched an unexpected CostTokenType which is not being used"),
};

let cost_count_value =
entry.const_int_from_type(context, location, *cost_count, u64_type)?;
let builtin_costs_index_value =
entry.const_int_from_type(context, location, builtin_costs_index, u64_type)?;

let builtin_cost_value_ptr = entry.gep(
context,
location,
builtin_ptr,
&[GepIndex::Value(builtin_costs_index_value)],
u64_type,
)?;
let cost_value = entry.load(context, location, builtin_cost_value_ptr, u64_type)?;
let gas_cost_value = entry.muli(cost_count_value, cost_value, location)?;
total_gas_cost_value = entry.addi(total_gas_cost_value, gas_cost_value, location)?;
}

let resulting_gas = entry.append_op_result(
ods::llvm::intr_uadd_sat(context, current_gas, total_gas_cost_value, location).into(),
)?;

entry.append_operation(helper.br(0, &[resulting_gas], location));

Ok(())
}

/// Generate MLIR operations for the `withdraw_gas_all` libfunc.
pub fn build_builtin_withdraw_gas<'ctx, 'this>(
context: &'ctx Context,
Expand Down Expand Up @@ -289,6 +363,6 @@ mod test {
);

let result = run_program(&program, "run_test", &[]);
assert_eq!(result.remaining_gas, Some(18446744073709545195));
assert_eq!(result.remaining_gas, Some(18446744073709545265));
}
}
Loading
Loading