Skip to content

Commit

Permalink
refactor(blockifier): use raw contract class in class info
Browse files Browse the repository at this point in the history
  • Loading branch information
noaov1 committed Nov 3, 2024
1 parent 148bc1e commit e145ec5
Show file tree
Hide file tree
Showing 17 changed files with 107 additions and 105 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

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

Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ fn test_declare(
version: tx_version,
resource_bounds: l1_resource_bounds(0_u8.into(), DEFAULT_STRK_L1_GAS_PRICE.into()),
},
calculate_class_info_for_testing(declared_contract.get_runnable_class()),
calculate_class_info_for_testing(declared_contract.get_class()),
)
.into();
tx_executor_test_body(state, block_context, tx, expected_bouncer_weights);
Expand Down
2 changes: 1 addition & 1 deletion crates/blockifier/src/concurrency/worker_logic_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ fn test_deploy_before_declare(
let account_address_1 = account_contract.get_instance_address(1);
let test_contract = FeatureContract::TestContract(cairo_version);
let test_class_hash = test_contract.get_class_hash();
let test_class_info = calculate_class_info_for_testing(test_contract.get_runnable_class());
let test_class_info = calculate_class_info_for_testing(test_contract.get_class());
let test_compiled_class_hash = test_contract.get_compiled_class_hash();
let declare_tx = declare_tx(
declare_tx_args! {
Expand Down
19 changes: 10 additions & 9 deletions crates/blockifier/src/execution/contract_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ fn convert_entry_points_v1(external: &[CasmContractEntryPoint]) -> Vec<EntryPoin
#[derive(Clone, Debug)]
// TODO(Ayelet,10/02/2024): Change to bytes.
pub struct ClassInfo {
contract_class: RunnableContractClass,
contract_class: ContractClass,
sierra_program_length: usize,
abi_length: usize,
}
Expand All @@ -539,16 +539,19 @@ impl TryFrom<starknet_api::contract_class::ClassInfo> for ClassInfo {
abi_length,
} = class_info;

Ok(Self { contract_class: contract_class.try_into()?, sierra_program_length, abi_length })
Ok(Self { contract_class: contract_class.clone(), sierra_program_length, abi_length })
}
}

impl ClassInfo {
pub fn bytecode_length(&self) -> usize {
self.contract_class.bytecode_length()
match &self.contract_class {
ContractClass::V0(contract_class) => contract_class.bytecode_length(),
ContractClass::V1(contract_class) => contract_class.bytecode.len(),
}
}

pub fn contract_class(&self) -> RunnableContractClass {
pub fn contract_class(&self) -> ContractClass {
self.contract_class.clone()
}

Expand All @@ -568,15 +571,13 @@ impl ClassInfo {
}

pub fn new(
contract_class: &RunnableContractClass,
contract_class: &ContractClass,
sierra_program_length: usize,
abi_length: usize,
) -> ContractClassResult<Self> {
let (contract_class_version, condition) = match contract_class {
RunnableContractClass::V0(_) => (0, sierra_program_length == 0),
RunnableContractClass::V1(_) => (1, sierra_program_length > 0),
#[cfg(feature = "cairo_native")]
RunnableContractClass::V1Native(_) => (1, sierra_program_length > 0),
ContractClass::V0(_) => (0, sierra_program_length == 0),
ContractClass::V1(_) => (1, sierra_program_length > 0),
};

if condition {
Expand Down
2 changes: 1 addition & 1 deletion crates/blockifier/src/fee/receipt_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(

// Declare.
for cairo_version in [CairoVersion::Cairo0, CairoVersion::Cairo1] {
let empty_contract = FeatureContract::Empty(cairo_version).get_runnable_class();
let empty_contract = FeatureContract::Empty(cairo_version).get_class();
let class_info = calculate_class_info_for_testing(empty_contract);
let declare_tx_starknet_resources = StarknetResources::new(
0,
Expand Down
20 changes: 15 additions & 5 deletions crates/blockifier/src/test_utils/contracts.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use starknet_api::contract_class::EntryPointType;
use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass;
use starknet_api::contract_class::{ContractClass, EntryPointType};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, EntryPointSelector};
use starknet_api::deprecated_contract_class::{
ContractClass as DeprecatedContractClass,
Expand All @@ -11,9 +12,10 @@ use strum_macros::EnumIter;

use crate::abi::abi_utils::selector_from_name;
use crate::abi::constants::CONSTRUCTOR_ENTRY_POINT_NAME;
use crate::execution::contract_class::{ContractClassV0, ContractClassV1, RunnableContractClass};
use crate::execution::contract_class::RunnableContractClass;
use crate::execution::entry_point::CallEntryPoint;
use crate::test_utils::cairo_compile::{cairo0_compile, cairo1_compile};
use crate::test_utils::struct_impls::LoadContractFromFile;
use crate::test_utils::{get_raw_contract_class, CairoVersion};

// This file contains featured contracts, used for tests. Use the function 'test_state' in
Expand Down Expand Up @@ -148,13 +150,21 @@ impl FeatureContract {
contract_address!(self.get_integer_base() + instance_id_as_u32 + ADDRESS_BIT)
}

pub fn get_runnable_class(&self) -> RunnableContractClass {
pub fn get_class(&self) -> ContractClass {
match self.cairo_version() {
CairoVersion::Cairo0 => ContractClassV0::from_file(&self.get_compiled_path()).into(),
CairoVersion::Cairo1 => ContractClassV1::from_file(&self.get_compiled_path()).into(),
CairoVersion::Cairo0 => {
ContractClass::V0(DeprecatedContractClass::from_file(&self.get_compiled_path()))
}
CairoVersion::Cairo1 => {
ContractClass::V1(CasmContractClass::from_file(&self.get_compiled_path()))
}
}
}

pub fn get_runnable_class(&self) -> RunnableContractClass {
self.get_class().try_into().unwrap()
}

// TODO(Arni, 1/1/2025): Remove this function, and use the get_class function instead.
pub fn get_deprecated_contract_class(&self) -> DeprecatedContractClass {
let mut raw_contract_class: serde_json::Value =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ use crate::abi::abi_utils::{
use crate::check_tx_execution_error_for_invalid_scenario;
use crate::context::{BlockContext, TransactionContext};
use crate::execution::call_info::CallInfo;
use crate::execution::contract_class::{ContractClassV1, RunnableContractClass};
use crate::execution::entry_point::EntryPointExecutionContext;
use crate::execution::syscalls::SyscallSelector;
use crate::fee::fee_utils::{get_fee_by_gas_vector, get_sequencer_balance_keys};
Expand Down Expand Up @@ -441,7 +440,7 @@ fn test_max_fee_limit_validate(
let grindy_validate_account = FeatureContract::AccountWithLongValidate(CairoVersion::Cairo1);
let grindy_class_hash = grindy_validate_account.get_class_hash();
let block_info = &block_context.block_info;
let class_info = calculate_class_info_for_testing(grindy_validate_account.get_runnable_class());
let class_info = calculate_class_info_for_testing(grindy_validate_account.get_class());

// Declare the grindy-validation account.
let account_tx = declare_tx(
Expand Down Expand Up @@ -748,7 +747,7 @@ fn test_fail_declare(block_context: BlockContext, max_fee: Fee) {
let TestInitData { mut state, account_address, mut nonce_manager, .. } =
create_test_init_data(chain_info, CairoVersion::Cairo0);
let class_hash = class_hash!(0xdeadeadeaf72_u128);
let contract_class = RunnableContractClass::V1(ContractClassV1::empty_for_testing());
let contract_class = FeatureContract::Empty(CairoVersion::Cairo1).get_class();
let next_nonce = nonce_manager.next(account_address);

// Cannot fail executing a declare tx unless it's V2 or above, and already declared.
Expand All @@ -758,7 +757,7 @@ fn test_fail_declare(block_context: BlockContext, max_fee: Fee) {
sender_address: account_address,
..Default::default()
};
state.set_contract_class(class_hash, contract_class.clone()).unwrap();
state.set_contract_class(class_hash, contract_class.clone().try_into().unwrap()).unwrap();
state.set_compiled_class_hash(class_hash, declare_tx.compiled_class_hash).unwrap();
let class_info = calculate_class_info_for_testing(contract_class);
let declare_account_tx = AccountTransaction::Declare(
Expand Down
14 changes: 6 additions & 8 deletions crates/blockifier/src/transaction/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rstest::fixture;
use starknet_api::block::GasPrice;
use starknet_api::contract_class::ContractClass;
use starknet_api::core::{ClassHash, ContractAddress, Nonce};
use starknet_api::execution_resources::GasAmount;
use starknet_api::test_utils::deploy_account::DeployAccountTxArgs;
Expand All @@ -25,7 +26,7 @@ use strum::IntoEnumIterator;

use crate::abi::abi_utils::get_fee_token_var_address;
use crate::context::{BlockContext, ChainInfo};
use crate::execution::contract_class::{ClassInfo, RunnableContractClass};
use crate::execution::contract_class::ClassInfo;
use crate::state::cached_state::CachedState;
use crate::state::state_api::State;
use crate::test_utils::contracts::FeatureContract;
Expand Down Expand Up @@ -259,8 +260,7 @@ pub fn create_account_tx_for_validate_test(
}
};
let class_hash = declared_contract.get_class_hash();
let class_info =
calculate_class_info_for_testing(declared_contract.get_runnable_class());
let class_info = calculate_class_info_for_testing(declared_contract.get_class());
declare_tx(
declare_tx_args! {
max_fee,
Expand Down Expand Up @@ -375,12 +375,10 @@ pub fn create_all_resource_bounds(
})
}

pub fn calculate_class_info_for_testing(contract_class: RunnableContractClass) -> ClassInfo {
pub fn calculate_class_info_for_testing(contract_class: ContractClass) -> ClassInfo {
let sierra_program_length = match contract_class {
RunnableContractClass::V0(_) => 0,
RunnableContractClass::V1(_) => 100,
#[cfg(feature = "cairo_native")]
RunnableContractClass::V1Native(_) => 100,
ContractClass::V0(_) => 0,
ContractClass::V1(_) => 100,
};
ClassInfo::new(&contract_class, sierra_program_length, 100).unwrap()
}
Expand Down
13 changes: 7 additions & 6 deletions crates/blockifier/src/transaction/transactions.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::sync::Arc;

use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use starknet_api::contract_class::EntryPointType;
use starknet_api::contract_class::{ContractClass, EntryPointType};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::transaction::{
AccountDeploymentData,
Expand All @@ -18,7 +18,7 @@ use starknet_api::transaction::{
use crate::abi::abi_utils::selector_from_name;
use crate::context::{BlockContext, TransactionContext};
use crate::execution::call_info::CallInfo;
use crate::execution::contract_class::{ClassInfo, RunnableContractClass};
use crate::execution::contract_class::ClassInfo;
use crate::execution::entry_point::{
CallEntryPoint,
CallType,
Expand Down Expand Up @@ -153,7 +153,8 @@ impl DeclareTransaction {
) -> TransactionExecutionResult<Self> {
let declare_version = declare_tx.version();
// Verify contract class version.
if !is_cairo1(&class_info.contract_class()) {
// TODO(Noa): Avoid the unnecessary conversion.
if !is_cairo1(&class_info.contract_class().try_into()?) {
if declare_version > TransactionVersion::ONE {
Err(TransactionExecutionError::ContractClassVersionMismatch {
declare_version,
Expand Down Expand Up @@ -212,7 +213,7 @@ impl DeclareTransaction {
self.tx_hash
}

pub fn contract_class(&self) -> RunnableContractClass {
pub fn contract_class(&self) -> ContractClass {
self.class_info.contract_class()
}

Expand All @@ -229,7 +230,7 @@ impl DeclareTransaction {
match state.get_compiled_contract_class(class_hash) {
Err(StateError::UndeclaredClassHash(_)) => {
// Class is undeclared; declare it.
state.set_contract_class(class_hash, self.contract_class())?;
state.set_contract_class(class_hash, self.contract_class().try_into()?)?;
if let Some(compiled_class_hash) = compiled_class_hash {
state.set_compiled_class_hash(class_hash, compiled_class_hash)?;
}
Expand Down Expand Up @@ -263,7 +264,7 @@ impl<S: State> Executable<S> for DeclareTransaction {
// We allow redeclaration of the class for backward compatibility.
// In the past, we allowed redeclaration of Cairo 0 contracts since there was
// no class commitment (so no need to check if the class is already declared).
state.set_contract_class(class_hash, self.contract_class())?;
state.set_contract_class(class_hash, self.contract_class().try_into()?)?;
}
}
starknet_api::transaction::DeclareTransaction::V2(DeclareTransactionV2 {
Expand Down
9 changes: 4 additions & 5 deletions crates/blockifier/src/transaction/transactions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -973,8 +973,7 @@ fn test_max_fee_exceeds_balance(
assert_resource_bounds_exceed_balance_failure(state, block_context, invalid_tx);
// Declare.
let contract_to_declare = FeatureContract::Empty(CairoVersion::Cairo1);
let class_info =
calculate_class_info_for_testing(contract_to_declare.get_runnable_class());
let class_info = calculate_class_info_for_testing(contract_to_declare.get_class());
let invalid_tx = declare_tx(
declare_tx_args! {
class_hash: contract_to_declare.get_class_hash(),
Expand Down Expand Up @@ -1439,7 +1438,7 @@ fn test_declare_tx(
let state = &mut test_state(chain_info, BALANCE, &[(account, 1)]);
let class_hash = empty_contract.get_class_hash();
let compiled_class_hash = empty_contract.get_compiled_class_hash();
let class_info = calculate_class_info_for_testing(empty_contract.get_runnable_class());
let class_info = calculate_class_info_for_testing(empty_contract.get_class());
let sender_address = account.get_instance_address(0);
let mut nonce_manager = NonceManager::default();
let state_changes_for_fee = declare_expected_state_changes_count(tx_version);
Expand Down Expand Up @@ -1567,7 +1566,7 @@ fn test_declare_tx(

// Verify class declaration.
let contract_class_from_state = state.get_compiled_contract_class(class_hash).unwrap();
assert_eq!(contract_class_from_state, class_info.contract_class());
assert_eq!(contract_class_from_state, class_info.contract_class().try_into().unwrap());

// Checks that redeclaring the same contract fails.
let account_tx2 = declare_tx(
Expand Down Expand Up @@ -1600,7 +1599,7 @@ fn test_declare_tx_v0(default_l1_resource_bounds: ValidResourceBounds) {
let state = &mut test_state(chain_info, BALANCE, &[(account, 1)]);
let class_hash = empty_contract.get_class_hash();
let compiled_class_hash = empty_contract.get_compiled_class_hash();
let class_info = calculate_class_info_for_testing(empty_contract.get_runnable_class());
let class_info = calculate_class_info_for_testing(empty_contract.get_class());
let sender_address = account.get_instance_address(0);
let mut nonce_manager = NonceManager::default();

Expand Down
1 change: 0 additions & 1 deletion crates/blockifier_reexecution/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ blockifier_regression_https_testing = []
blockifier.workspace = true
cairo-lang-starknet-classes.workspace = true
cairo-lang-utils.workspace = true
cairo-vm.workspace = true
clap = { workspace = true, features = ["cargo", "derive"] }
flate2.workspace = true
indexmap = { workspace = true, features = ["serde"] }
Expand Down
30 changes: 13 additions & 17 deletions crates/blockifier_reexecution/src/state_reader/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,20 @@

use std::collections::HashMap;
use std::io::{self, Read};
use std::sync::Arc;

use blockifier::execution::contract_class::{
ContractClassV0,
ContractClassV0Inner,
RunnableContractClass,
};
use blockifier::state::state_api::StateResult;
use cairo_lang_starknet_classes::contract_class::ContractEntryPoints;
use cairo_lang_utils::bigint::BigUintAsHex;
use cairo_vm::types::program::Program;
use flate2::bufread;
use serde::Deserialize;
use starknet_api::contract_class::EntryPointType;
use starknet_api::contract_class::{ContractClass, EntryPointType};
use starknet_api::core::EntryPointSelector;
use starknet_api::deprecated_contract_class::{EntryPointOffset, EntryPointV0};
use starknet_api::deprecated_contract_class::{
ContractClass as DeprecatedContractClass,
EntryPointOffset,
EntryPointV0,
Program,
};
use starknet_api::hash::StarkHash;
use starknet_core::types::{
CompressedLegacyContractClass,
Expand Down Expand Up @@ -75,9 +73,7 @@ pub fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
}

/// Compile a FlattenedSierraClass to a ContractClass V1 (casm) using cairo_lang_starknet_classes.
pub fn sierra_to_contact_class_v1(
sierra: FlattenedSierraClass,
) -> StateResult<RunnableContractClass> {
pub fn sierra_to_contact_class_v1(sierra: FlattenedSierraClass) -> StateResult<ContractClass> {
let middle_sierra: MiddleSierraContractClass = {
let v = serde_json::to_value(sierra).map_err(serde_err_to_state_err);
serde_json::from_value(v?).map_err(serde_err_to_state_err)?
Expand All @@ -96,17 +92,17 @@ pub fn sierra_to_contact_class_v1(
false,
usize::MAX,
)
// TODO(Aviv): Reconsider the unwrap.
.unwrap();
Ok(RunnableContractClass::V1(casm.try_into().unwrap()))
Ok(ContractClass::V1(casm))
}

/// Compile a CompressedLegacyContractClass to a ContractClass V0 using cairo_lang_starknet_classes.
pub fn legacy_to_contract_class_v0(
legacy: CompressedLegacyContractClass,
) -> StateResult<RunnableContractClass> {
) -> StateResult<ContractClass> {
let as_str = decode_reader(legacy.program).unwrap();
let program = Program::from_bytes(as_str.as_bytes(), None).unwrap();
let program: Program = serde_json::from_str(&as_str).unwrap();
let entry_points_by_type = map_entry_points_by_type_legacy(legacy.entry_points_by_type);
let inner = Arc::new(ContractClassV0Inner { program, entry_points_by_type });
Ok(RunnableContractClass::V0(ContractClassV0(inner)))
Ok((DeprecatedContractClass { program, entry_points_by_type, abi: None }).into())
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,12 @@ impl StateReader for TestStateReader {
class_hash: ClassHash,
) -> StateResult<RunnableContractClass> {
match self.get_contract_class(&class_hash)? {
StarknetContractClass::Sierra(sierra) => sierra_to_contact_class_v1(sierra),
StarknetContractClass::Legacy(legacy) => legacy_to_contract_class_v0(legacy),
StarknetContractClass::Sierra(sierra) => {
Ok(sierra_to_contact_class_v1(sierra).unwrap().try_into().unwrap())
}
StarknetContractClass::Legacy(legacy) => {
Ok(legacy_to_contract_class_v0(legacy).unwrap().try_into().unwrap())
}
}
}

Expand Down
Loading

0 comments on commit e145ec5

Please sign in to comment.