Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
27 changes: 24 additions & 3 deletions crates/apollo_infra_utils/src/cairo0_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct CairoLangVersion<'a>(pub &'a str);

pub const EXPECTED_CAIRO0_STARKNET_COMPILE_VERSION: CairoLangVersion<'static> =
CairoLangVersion("0.14.0.1");
pub const EXPECTED_CAIRO0_VERSION: CairoLangVersion<'static> = CairoLangVersion("0.14.1a0");
pub const EXPECTED_CAIRO0_VERSION: CairoLangVersion<'static> = CairoLangVersion("0.14.3a1");

/// The local python requirements used to determine the cairo0 compiler version.
pub(crate) static PIP_REQUIREMENTS_FILE: LazyLock<PathBuf> =
Expand All @@ -26,6 +26,15 @@ pub(crate) static STARKNET_DEPRECATED_COMPILE_REQUIREMENTS_FILE: LazyLock<PathBu
.unwrap()
});

fn find_script_in_path(script_name: &str) -> Option<PathBuf> {
std::env::var_os("PATH").and_then(|paths| {
std::env::split_paths(&paths).find_map(|dir| {
let candidate = dir.join(script_name);
candidate.exists().then_some(candidate)
})
})
}

pub(crate) fn enter_venv_instructions(script_type: &Cairo0Script) -> String {
format!(
r#"
Expand Down Expand Up @@ -65,6 +74,18 @@ impl Cairo0Script {
Self::StarknetCompileDeprecated => &STARKNET_DEPRECATED_COMPILE_REQUIREMENTS_FILE,
}
}

pub(crate) fn command(&self) -> Result<Command, Cairo0ScriptVersionError> {
let script = self.script_name();
let script_path =
find_script_in_path(script).ok_or(Cairo0ScriptVersionError::CompilerNotFound {
script: *self,
error: format!("Failed to find {script} in PATH."),
})?;
let mut cmd = Command::new("python");
cmd.arg(script_path);
Ok(cmd)
}
}

#[derive(thiserror::Error, Debug)]
Expand Down Expand Up @@ -103,7 +124,7 @@ pub fn cairo0_script_correct_version(
) -> Result<(), Cairo0ScriptVersionError> {
let expected_version = script_type.required_version();
let script = script_type.script_name();
let version = match Command::new(script).arg("--version").output() {
let version = match script_type.command()?.arg("--version").output() {
Ok(output) => String::from_utf8_lossy(&output.stdout).to_string(),
Err(error) => {
return Err(Cairo0ScriptVersionError::CompilerNotFound {
Expand Down Expand Up @@ -142,7 +163,7 @@ pub fn compile_cairo0_program(
if !cairo_root_path.exists() {
return Err(Cairo0CompilerError::CairoRootNotFound(cairo_root_path));
}
let mut compile_command = Command::new(script_type.script_name());
let mut compile_command = script_type.command()?;
compile_command.args([
path_to_main.to_str().ok_or(Cairo0CompilerError::InvalidPath(path_to_main.clone()))?,
"--debug_info_with_source",
Expand Down
12 changes: 9 additions & 3 deletions crates/apollo_infra_utils/src/cairo0_compiler_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,9 @@ pub fn cairo0_format_batch<S: AsRef<str>>(files: HashMap<String, S>) -> HashMap<
}

// Run cairo-format on all files at once with -i (in-place).
let format_script = script_type.script_name();
let mut format_command = Command::new(format_script);
let mut format_command = script_type
.command()
.expect("cairo-format must be available after verify_cairo0_compiler_deps");
format_command.arg("-i");
for path in &file_paths {
format_command.arg(path);
Expand All @@ -245,7 +246,12 @@ pub fn cairo0_format_batch<S: AsRef<str>>(files: HashMap<String, S>) -> HashMap<
for (path, original) in file_paths.iter().zip(pre_format_contents.iter()) {
if std::fs::metadata(path).unwrap().len() == 0 && !original.is_empty() {
std::fs::write(path, original).unwrap();
let output = Command::new(format_script).arg(path).output().unwrap();
let output = script_type
.command()
.expect("cairo-format must be available after verify_cairo0_compiler_deps")
.arg(path)
.output()
.unwrap();
assert!(
output.status.success(),
"cairo-format stdout retry failed for {path:?}: {}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ const STORED_BLOCK_HASH_BUFFER = 10;
const ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_0 = (
0x03e98c2d7703b03a7edb73ed7f075f97f1dcbaa8f717cdf6e1a57bf058265473
);
const ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_LEN = 1;
const ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_1 = (
0x039f55918423cade9e95a6a52286b56bed1c5c9b6fe39aa00301361457a3c604
);
const ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_LEN = 2;

// Gas constants.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ from starkware.cairo.common.dict_access import DictAccess
from starkware.cairo.common.math import assert_le, assert_nn_le, assert_not_zero
from starkware.starknet.core.os.constants import (
ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_0,
ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_1,
ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_LEN,
STORED_BLOCK_HASH_BUFFER,
)
Expand All @@ -23,8 +24,9 @@ func check_is_reverted(is_reverted: felt) {

// Returns TRUE if the given virtual OS program hash is allowed, FALSE otherwise.
func is_program_hash_allowed(program_hash: felt) -> felt {
static_assert ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_LEN == 1;
if (program_hash == ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_0) {
static_assert ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_LEN == 2;
if ((program_hash - ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_0) *
(program_hash - ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_1) == 0) {
return TRUE;
}
return FALSE;
Expand Down
8 changes: 4 additions & 4 deletions crates/apollo_starknet_os_program/src/program_hash.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"os": "0xb0134eed363da4094afca019a74939b4c17f238a4f7411798813f55905cd7",
"virtual_os": "0x3e98c2d7703b03a7edb73ed7f075f97f1dcbaa8f717cdf6e1a57bf058265473",
"aggregator": "0x43666b81f964bcdedf0098d2791b061d61f3098ff1429a754d0b97eeeae9489",
"aggregator_with_prefix": "0x68072c8f5ff5ae133060e12cfad3a38362dbb6d667abd4f7e1fac6f37febe46"
"os": "0x10e4d1fd519f4675b021671fb866ec60fc0522f65273f587255414d0e5d5b23",
"virtual_os": "0x39f55918423cade9e95a6a52286b56bed1c5c9b6fe39aa00301361457a3c604",
"aggregator": "0x700786d51b3854af43d8e12180380bda3029be6c1767e007858de6ca2edac40",
"aggregator_with_prefix": "0xe08d300e3f5996e43d6d7cc5a20068e0e58cf1309089f2348317ac580f6c1f"
}
4 changes: 2 additions & 2 deletions crates/apollo_starknet_os_program/src/virtual_os_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ fn test_virtual_os_swapped_files() {
#[test]
fn test_program_bytecode_lengths() {
expect![[r#"
15610
15660
"#]]
.assert_debug_eq(&OS_PROGRAM.data_len());
expect![[r#"
10214
10261
"#]]
.assert_debug_eq(&VIRTUAL_OS_PROGRAM.data_len());
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
"segment_arena_cells": false,
"os_constants": {
"allowed_virtual_os_program_hashes": [
"0x3e98c2d7703b03a7edb73ed7f075f97f1dcbaa8f717cdf6e1a57bf058265473"
"0x3e98c2d7703b03a7edb73ed7f075f97f1dcbaa8f717cdf6e1a57bf058265473",
"0x39f55918423cade9e95a6a52286b56bed1c5c9b6fe39aa00301361457a3c604"
],
"constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194",
"default_entry_point_selector": "0x0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
~ /enable_casm_hash_migration: true
+ /os_constants/allowed_virtual_os_program_hashes/1: "0x39f55918423cade9e95a6a52286b56bed1c5c9b6fe39aa00301361457a3c604"
4 changes: 2 additions & 2 deletions crates/blockifier/src/bouncer_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -804,11 +804,11 @@ fn class_hash_migration_data_from_state(

if should_migrate {
expect![[r#"
111245775
108608775
"#]]
.assert_debug_eq(&migration_sierra_gas.0);
expect![[r#"
269417662
266780662
"#]]
.assert_debug_eq(&migration_proving_gas.0);
} else {
Expand Down
44 changes: 28 additions & 16 deletions crates/blockifier/src/execution/casm_hash_estimation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,49 +250,61 @@ impl CasmV2HashResourceEstimate {

// Base number of VM steps applied when the input to Blake hashing is empty.
// Determined empirically by running `encode_felt252_data_and_calc_blake_hash` on empty input.
pub(crate) const STEPS_EMPTY_INPUT: usize = 170;
pub(crate) const STEPS_EMPTY_INPUT: usize = 167;

/// Estimates the number of VM steps required to hash the given felts with Blake in Starknet OS.
///
/// - Each small felt unpacks into 2 `u32`s.
/// - Each large felt unpacks into 8 `u32`s.
/// - Adds a base cost depending on whether the total encoded `u32` sequence fits exactly into
/// full 16-`u32` Blake messages.
/// - Each full 16-`u32` message processed after the first amortizes 2 steps off the base,
/// reflecting per-block fixed overhead that is shared across iterations.
fn estimate_steps_of_encode_felt252_data_and_calc_blake_hash(
felt_size_groups: &FeltSizeCount,
) -> usize {
// The constants used are empirical, based on running
// `encode_felt252_data_and_calc_blake_hash` on combinations of large and small
// felts. VM steps per large felt.
const STEPS_PER_LARGE_FELT: usize = 45;
// felts and varying numbers of Blake messages. VM steps per large felt.
const STEPS_PER_LARGE_FELT: usize = 38;
// VM steps per small felt.
const STEPS_PER_SMALL_FELT: usize = 15;
// Base overhead when input exactly fills a 16-u32 Blake message.
const BASE_STEPS_FULL_MSG: usize = 217;
// Base overhead when the input leaves a remainder (< 16 u32s) for a Blake message.
const BASE_STEPS_PARTIAL_MSG: usize = 195;
// Base overhead when input exactly fills full 16-u32 Blake messages, before per-message
// amortization.
const BASE_STEPS_FULL_MSG: usize = 216;
// Base overhead when the input leaves a remainder (< 16 u32s) for a Blake message, before
// per-message amortization.
const BASE_STEPS_PARTIAL_MSG: usize = 192;
// Extra VM steps added per 2-u32 remainder in partial Blake messages.
const STEPS_PER_2_U32_REMINDER: usize = 3;
// VM steps saved per full Blake message processed (amortized fixed-cost per block).
const STEPS_DISCOUNT_PER_FULL_MSG: usize = 2;

let encoded_u32_len = felt_size_groups.encoded_u32_len();
if encoded_u32_len == 0 {
// The empty input case is a special case.
return Self::STEPS_EMPTY_INPUT;
}

// Adds a base cost depending on whether the total fits exactly into full 16-u32 messages.
let base_steps = if encoded_u32_len.is_multiple_of(Self::U32_WORDS_PER_MESSAGE) {
let n_full_msgs = encoded_u32_len / Self::U32_WORDS_PER_MESSAGE;
let rem_u32s = encoded_u32_len % Self::U32_WORDS_PER_MESSAGE;

// Pick base cost depending on whether the total fits exactly into full 16-u32 messages.
// Note: all inputs expand to an even number of u32s --> `rem_u32s` is always even.
let base_steps = if rem_u32s == 0 {
BASE_STEPS_FULL_MSG
} else {
// This computation is based on running blake2s with different inputs.
// Note: all inputs expand to an even number of u32s --> `rem_u32s` is always even.
BASE_STEPS_PARTIAL_MSG
+ (encoded_u32_len % Self::U32_WORDS_PER_MESSAGE / 2) * STEPS_PER_2_U32_REMINDER
BASE_STEPS_PARTIAL_MSG + (rem_u32s / 2) * STEPS_PER_2_U32_REMINDER
};

base_steps
+ felt_size_groups.large * STEPS_PER_LARGE_FELT
+ felt_size_groups.small * STEPS_PER_SMALL_FELT
let per_felt_steps = felt_size_groups.large * STEPS_PER_LARGE_FELT
+ felt_size_groups.small * STEPS_PER_SMALL_FELT;
let discount = n_full_msgs * STEPS_DISCOUNT_PER_FULL_MSG;

// `per_felt_steps + base_steps` always dominates `discount` for any non-degenerate input
// (per-felt costs grow 19x faster than the per-message discount), so saturating_sub only
// matters as a defensive guard.
(per_felt_steps + base_steps).saturating_sub(discount)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@
{
"StatelessHint": "SetNUpdatesSmall"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@
{
"StatelessHint": "SetStateUpdatesStart"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@
{
"StatelessHint": "SetNUpdatesSmall"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@
{
"StatelessHint": "SetStateUpdatesStart"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@
{
"StatelessHint": "SetNUpdatesSmall"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@
{
"StatelessHint": "SetStateUpdatesStart"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@
{
"StatelessHint": "SetNUpdatesSmall"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@
{
"StatelessHint": "SetStateUpdatesStart"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,6 @@
{
"StatelessHint": "SetNUpdatesSmall"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@
{
"StatelessHint": "SetNUpdatesSmall"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@
{
"StatelessHint": "SetNUpdatesSmall"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@
{
"StatelessHint": "SetNUpdatesSmall"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@
{
"StatelessHint": "SetNUpdatesSmall"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@
{
"StatelessHint": "SetNUpdatesSmall"
},
{
"StatelessHint": "SetSiblings"
},
{
"StatelessHint": "IsCaseRight"
},
Expand Down
Loading