Skip to content

Commit

Permalink
feat(blockifier): update to cairo native 0.2.2-alpha.0
Browse files Browse the repository at this point in the history
refactor(blockifier): modify entry point logic from native runnable class

refactor(blockifier): apply general improvements

refactor(blockifier): make casm constructor public
  • Loading branch information
rodrigo-pino committed Nov 18, 2024
1 parent 404599e commit 61c6345
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 98 deletions.
9 changes: 4 additions & 5 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ cairo-lang-sierra-to-casm = "2.9.0-dev.0"
cairo-lang-starknet-classes = "2.9.0-dev.0"
cairo-lang-utils = "2.9.0-dev.0"
# Important: when updated, make sure to update the cairo-native submodule as well.
cairo-native = "0.2.1-alpha.0"
cairo-native = "0.2.2-alpha.0"
cairo-vm = "=1.0.1"
camelpaste = "0.1.0"
chrono = "0.4.26"
Expand Down
1 change: 0 additions & 1 deletion crates/blockifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ ark-secp256r1.workspace = true
cached.workspace = true
cairo-lang-casm = { workspace = true, features = ["parity-scale-codec"] }
cairo-lang-runner.workspace = true
cairo-lang-sierra.workspace = true
cairo-lang-starknet-classes.workspace = true
cairo-native = { workspace = true, optional = true }
cairo-vm.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/blockifier/cairo_native
Submodule cairo_native updated 72 files
+19 −0 .github/ISSUE_TEMPLATE/daily_failure.md
+36 −0 .github/actions/install-linux-deps/action.yml
+2 −6 .github/workflows/bench-hyperfine.yml
+175 −0 .github/workflows/daily.yml
+150 −0 .github/workflows/starknet-blocks.yml
+64 −63 Cargo.lock
+3 −2 Cargo.toml
+2 −1 Makefile
+18 −82 benches/benches.rs
+17 −0 benches/compile_time.rs
+54 −3 benches/libfuncs.rs
+15 −1 docs/sierra.md
+8 −0 examples/erc20.rs
+8 −0 examples/starknet.rs
+8 −3 programs/benches/factorial_2M.c
+8 −3 programs/benches/fib_2M.c
+8 −3 programs/benches/logistic_map.c
+42 −48 programs/compile_benches/dijkstra.cairo
+8 −17 programs/compile_benches/extended_euclidean_algorithm.cairo
+78 −27 programs/compile_benches/fast_power.cairo
+0 −285 programs/compile_benches/sha256.cairo
+539 −0 programs/compile_benches/sha512.cairo
+1 −1 runtime/Cargo.toml
+28 −1 runtime/src/lib.rs
+10 −38 scripts/bench-hyperfine.sh
+51 −0 scripts/cmp_state_dumps.sh
+30 −0 scripts/diff-check.sh
+2 −9 src/arch/aarch64.rs
+2 −9 src/arch/x86_64.rs
+1 −0 src/bin/utils/mod.rs
+13 −12 src/cache/aot.rs
+10 −8 src/cache/jit.rs
+20 −11 src/compiler.rs
+107 −0 src/error.rs
+81 −32 src/executor.rs
+51 −3 src/executor/aot.rs
+328 −46 src/executor/contract.rs
+23 −2 src/executor/jit.rs
+2 −1 src/ffi.rs
+13 −8 src/libfuncs.rs
+28 −17 src/libfuncs/array.rs
+43 −10 src/libfuncs/bounded_int.rs
+4 −1 src/libfuncs/cast.rs
+5 −3 src/libfuncs/circuit.rs
+10 −5 src/libfuncs/const.rs
+2 −2 src/libfuncs/debug.rs
+9 −4 src/libfuncs/enum.rs
+9 −2 src/libfuncs/felt252.rs
+2 −2 src/libfuncs/felt252_dict_entry.rs
+3 −2 src/libfuncs/function_call.rs
+125 −33 src/libfuncs/gas.rs
+181 −0 src/libfuncs/int_range.rs
+456 −602 src/libfuncs/starknet.rs
+676 −1,507 src/libfuncs/starknet/secp256.rs
+40 −7 src/metadata/gas.rs
+44 −0 src/metadata/runtime_bindings.rs
+43 −2 src/starknet.rs
+8 −0 src/starknet_stub.rs
+24 −9 src/types.rs
+19 −24 src/types/array.rs
+6 −2 src/types/builtin_costs.rs
+46 −0 src/types/int_range.rs
+110 −2 src/utils.rs
+87 −1 src/utils/block_ext.rs
+65 −3 src/values.rs
+6 −6 tests/alexandria/Scarb.lock
+4 −4 tests/alexandria/Scarb.toml
+33 −17 tests/common.rs
+13 −2 tests/tests/starknet/keccak.rs
+6 −1 tests/tests/starknet/programs/syscalls.cairo
+8 −0 tests/tests/starknet/secp256.rs
+28 −0 tests/tests/starknet/syscalls.rs
2 changes: 1 addition & 1 deletion crates/blockifier/src/execution/contract_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ impl Deref for ContractClassV1 {
}

impl ContractClassV1 {
fn constructor_selector(&self) -> Option<EntryPointSelector> {
pub fn constructor_selector(&self) -> Option<EntryPointSelector> {
self.0.entry_points_by_type.constructor.first().map(|ep| ep.selector)
}

Expand Down
90 changes: 12 additions & 78 deletions crates/blockifier/src/execution/native/contract_class.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
use std::ops::Deref;
use std::sync::Arc;

use cairo_lang_sierra::ids::FunctionId;
use cairo_lang_starknet_classes::contract_class::{
ContractClass as SierraContractClass,
ContractEntryPoint as SierraContractEntryPoint,
};
use cairo_native::executor::AotContractExecutor;
use starknet_api::core::EntryPointSelector;

use crate::execution::contract_class::{ContractClassV1, EntryPointsByType, HasSelector};
use crate::execution::contract_class::{ContractClassV1, EntryPointV1};
use crate::execution::entry_point::CallEntryPoint;
use crate::execution::errors::PreExecutionError;
use crate::execution::native::utils::contract_entrypoint_to_entrypoint_selector;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NativeContractClassV1(pub Arc<NativeContractClassV1Inner>);
impl Deref for NativeContractClassV1 {
Expand All @@ -25,26 +19,24 @@ impl Deref for NativeContractClassV1 {

impl NativeContractClassV1 {
pub(crate) fn constructor_selector(&self) -> Option<EntryPointSelector> {
self.entry_points_by_type.constructor.first().map(|ep| ep.selector)
self.casm.constructor_selector()
}

/// Initialize a compiled contract class for native.
///
/// executor must be derived from sierra_program which in turn must be derived from
/// sierra_contract_class.
pub fn new(
executor: AotContractExecutor,
sierra_contract_class: SierraContractClass,
casm: ContractClassV1,
) -> NativeContractClassV1 {
let contract = NativeContractClassV1Inner::new(executor, sierra_contract_class, casm);
pub fn new(executor: AotContractExecutor, casm: ContractClassV1) -> NativeContractClassV1 {
let contract = NativeContractClassV1Inner::new(executor, casm);

Self(Arc::new(contract))
}

/// Returns an entry point into the natively compiled contract.
pub fn get_entry_point(&self, call: &CallEntryPoint) -> Result<FunctionId, PreExecutionError> {
self.entry_points_by_type.get_entry_point(call).map(|ep| ep.function_id)
pub fn get_entry_point(
&self,
call: &CallEntryPoint,
) -> Result<EntryPointV1, PreExecutionError> {
self.casm.get_entry_point(call)
}

pub fn casm(&self) -> ContractClassV1 {
Expand All @@ -55,79 +47,21 @@ impl NativeContractClassV1 {
#[derive(Debug)]
pub struct NativeContractClassV1Inner {
pub executor: AotContractExecutor,
entry_points_by_type: EntryPointsByType<NativeEntryPoint>,
casm: ContractClassV1,
}

impl NativeContractClassV1Inner {
fn new(
executor: AotContractExecutor,
sierra_contract_class: SierraContractClass,
casm: ContractClassV1,
) -> Self {
NativeContractClassV1Inner {
executor,
entry_points_by_type: EntryPointsByType::from(&sierra_contract_class),
casm,
}
fn new(executor: AotContractExecutor, casm: ContractClassV1) -> Self {
NativeContractClassV1Inner { executor, casm }
}
}

// The location where the compiled contract is loaded into memory will not
// be the same therefore we exclude it from the comparison.
impl PartialEq for NativeContractClassV1Inner {
fn eq(&self, other: &Self) -> bool {
self.entry_points_by_type == other.entry_points_by_type && self.casm == other.casm
self.casm == other.casm
}
}

impl Eq for NativeContractClassV1Inner {}

impl From<&SierraContractClass> for EntryPointsByType<NativeEntryPoint> {
fn from(sierra_contract_class: &SierraContractClass) -> Self {
let program =
sierra_contract_class.extract_sierra_program().expect("Can't get sierra program.");

let func_ids = program.funcs.iter().map(|func| &func.id).collect::<Vec<&FunctionId>>();

let entry_points_by_type = &sierra_contract_class.entry_points_by_type;

EntryPointsByType::<NativeEntryPoint> {
constructor: sierra_eps_to_native_eps(&func_ids, &entry_points_by_type.constructor),
external: sierra_eps_to_native_eps(&func_ids, &entry_points_by_type.external),
l1_handler: sierra_eps_to_native_eps(&func_ids, &entry_points_by_type.l1_handler),
}
}
}

fn sierra_eps_to_native_eps(
func_ids: &[&FunctionId],
sierra_eps: &[SierraContractEntryPoint],
) -> Vec<NativeEntryPoint> {
sierra_eps.iter().map(|sierra_ep| NativeEntryPoint::from(func_ids, sierra_ep)).collect()
}

#[derive(Clone, Debug, PartialEq)]
/// Provides a relation between a function in a contract and a compiled contract.
pub struct NativeEntryPoint {
/// The selector is the key to find the function in the contract.
selector: EntryPointSelector,
/// And the function_id is the key to find the function in the compiled contract.
function_id: FunctionId,
}

impl NativeEntryPoint {
fn from(func_ids: &[&FunctionId], sierra_ep: &SierraContractEntryPoint) -> NativeEntryPoint {
let &function_id = func_ids.get(sierra_ep.function_idx).expect("Can't find function id.");
NativeEntryPoint {
selector: contract_entrypoint_to_entrypoint_selector(sierra_ep),
function_id: function_id.clone(),
}
}
}

impl HasSelector for NativeEntryPoint {
fn selector(&self) -> &EntryPointSelector {
&self.selector
}
}
19 changes: 17 additions & 2 deletions crates/blockifier/src/execution/native/entry_point_execution.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cairo_native::execution_result::ContractExecutionResult;
use cairo_native::utils::BuiltinCosts;
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use num_traits::ToPrimitive;
use starknet_api::execution_resources::GasAmount;
Expand All @@ -15,22 +16,36 @@ use crate::execution::native::contract_class::NativeContractClassV1;
use crate::execution::native::syscall_handler::NativeSyscallHandler;
use crate::state::state_api::State;

// todo(rodrigo): add an `entry point not found` test for Native
pub fn execute_entry_point_call(
call: CallEntryPoint,
contract_class: NativeContractClassV1,
state: &mut dyn State,
resources: &mut ExecutionResources,
context: &mut EntryPointExecutionContext,
) -> EntryPointExecutionResult<CallInfo> {
let function_id = contract_class.get_entry_point(&call)?;
let entry_point = contract_class.get_entry_point(&call)?;

let mut syscall_handler: NativeSyscallHandler<'_> =
NativeSyscallHandler::new(call, state, resources, context);

let gas_costs = &syscall_handler.context.versioned_constants().os_constants.gas_costs;
let builtin_costs = BuiltinCosts {
// todo(rodrigo): Unsure of what value `const` means, but 1 is the right value
r#const: 1,
pedersen: gas_costs.pedersen_gas_cost,
bitwise: gas_costs.bitwise_builtin_gas_cost,
ecop: gas_costs.ecop_gas_cost,
poseidon: gas_costs.poseidon_gas_cost,
add_mod: gas_costs.add_mod_gas_cost,
mul_mod: gas_costs.mul_mod_gas_cost,
};

let execution_result = contract_class.executor.run(
&function_id,
entry_point.selector.0,
&syscall_handler.call.calldata.0.clone(),
Some(syscall_handler.call.initial_gas.into()),
Some(builtin_costs),
&mut syscall_handler,
);

Expand Down
8 changes: 8 additions & 0 deletions crates/blockifier/src/execution/native/syscall_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,14 @@ impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> {
})
}

fn get_class_hash_at(
&mut self,
_contract_address: Felt,
_remaining_gas: &mut u128,
) -> SyscallResult<Felt> {
todo!()
}

fn get_execution_info_v2(
&mut self,
remaining_gas: &mut u128,
Expand Down
19 changes: 10 additions & 9 deletions crates/blockifier/src/test_utils/struct_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,20 +250,21 @@ impl NativeContractClassV1 {
.extract_sierra_program()
.expect("Cannot extract sierra program from sierra contract class");

let executor = AotContractExecutor::new(&sierra_program, cairo_native::OptLevel::Default)
.expect("Cannot compile sierra into native");
let executor = AotContractExecutor::new(
&sierra_program,
&sierra_contract_class.entry_points_by_type,
cairo_native::OptLevel::Default,
)
.expect("Cannot compile sierra into native");

// Compile the sierra contract class into casm
let casm_contract_class = CasmContractClass::from_contract_class(
sierra_contract_class.clone(),
false,
usize::MAX,
)
.expect("Cannot compile sierra contract class into casm contract class");
let casm_contract_class =
CasmContractClass::from_contract_class(sierra_contract_class, false, usize::MAX)
.expect("Cannot compile sierra contract class into casm contract class");
let casm = ContractClassV1::try_from(casm_contract_class)
.expect("Cannot get ContractClassV1 from CasmContractClass");

NativeContractClassV1::new(executor, sierra_contract_class, casm)
NativeContractClassV1::new(executor, casm)
}

pub fn from_file(contract_path: &str) -> Self {
Expand Down

0 comments on commit 61c6345

Please sign in to comment.