Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
refactor(transaction): remove public fields, add new function
Browse files Browse the repository at this point in the history
  • Loading branch information
ayeletstarkware committed Feb 12, 2024
1 parent fce18e1 commit 89f27e6
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 59 deletions.
51 changes: 50 additions & 1 deletion crates/blockifier/src/execution/contract_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ use starknet_api::deprecated_contract_class::{
use crate::abi::abi_utils::selector_from_name;
use crate::abi::constants::{self, CONSTRUCTOR_ENTRY_POINT_NAME};
use crate::execution::entry_point::CallEntryPoint;
use crate::execution::errors::PreExecutionError;
use crate::execution::errors::{ContractClassError, PreExecutionError};
use crate::execution::execution_utils::{felt_to_stark_felt, sn_api_to_cairo_vm_program};
/// Represents a runnable Starknet contract class (meaning, the program is runnable by the VM).
/// We wrap the actual class in an Arc to avoid cloning the program when cloning the class.
// Note: when deserializing from a SN API class JSON string, the ABI field is ignored
// by serde, since it is not required for execution.

pub type ContractClassResult<T> = Result<T, ContractClassError>;

#[derive(Clone, Debug, Eq, PartialEq, derive_more::From)]
pub enum ContractClass {
V0(ContractClassV0),
Expand Down Expand Up @@ -393,3 +396,49 @@ fn convert_entry_points_v1(
})
.collect()
}

#[derive(Clone, Debug)]
// TODO(Ayelet,10/02/2024): Change to bytes.
pub struct ClassInfo {
contract_class: ContractClass,
sierra_program_length: usize,
abi_length: usize,
}

impl ClassInfo {
pub fn bytecode_length(&self) -> usize {
self.contract_class.bytecode_length()
}

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

pub fn sierra_program_length(&self) -> usize {
self.sierra_program_length
}

pub fn abi_length(&self) -> usize {
self.abi_length
}

pub fn new(
contract_class: &ContractClass,
sierra_program_length: usize,
abi_length: usize,
) -> ContractClassResult<Self> {
let (contract_class_version, condition) = match contract_class {
ContractClass::V0(_) => (0, sierra_program_length == 0),
ContractClass::V1(_) => (1, sierra_program_length > 0),
};

if condition {
Ok(Self { contract_class: contract_class.clone(), sierra_program_length, abi_length })
} else {
Err(ContractClassError::ContractClassVersionSierraProgramLengthMismatch {
contract_class_version,
sierra_program_length,
})
}
}
}
12 changes: 12 additions & 0 deletions crates/blockifier/src/execution/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,15 @@ pub enum EntryPointExecutionError {
source: CairoRunError,
},
}

#[derive(Debug, Error)]
pub enum ContractClassError {
#[error(
"Sierra program length must be > 0 for Cairo1, and == 0 for Cairo0. Got: \
{sierra_program_length:?} for contract class version {contract_class_version:?}"
)]
ContractClassVersionSierraProgramLengthMismatch {
contract_class_version: u8,
sierra_program_length: usize,
},
}
2 changes: 1 addition & 1 deletion crates/blockifier/src/fee/actual_cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use starknet_api::transaction::Fee;
use crate::abi::constants as abi_constants;
use crate::context::TransactionContext;
use crate::execution::call_info::CallInfo;
use crate::execution::contract_class::ClassInfo;
use crate::fee::gas_usage::{
get_calldata_and_signature_gas_cost, get_code_gas_cost, get_da_gas_cost, get_messages_gas_cost,
get_tx_events_gas_cost,
Expand All @@ -18,7 +19,6 @@ use crate::transaction::objects::{
};
use crate::transaction::transaction_types::TransactionType;
use crate::transaction::transaction_utils::calculate_tx_resources;
use crate::transaction::transactions::ClassInfo;
use crate::versioned_constants::VersionedConstants;

#[cfg(test)]
Expand Down
6 changes: 3 additions & 3 deletions crates/blockifier/src/fee/actual_cost_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ fn test_calculate_tx_gas_usage_basic(#[values(false, true)] use_kzg_da: bool) {
// Declare.
for cairo_version in [CairoVersion::Cairo0, CairoVersion::Cairo1] {
let empty_contract = FeatureContract::Empty(cairo_version).get_class();
let class_info = calculate_class_info_for_testing(cairo_version, empty_contract);
let class_info = calculate_class_info_for_testing(empty_contract);
let code_milligas_cost = u128_from_usize(
(class_info.bytecode_length() + class_info.sierra_program_length)
(class_info.bytecode_length() + class_info.sierra_program_length())
* eth_gas_constants::WORD_WIDTH
+ class_info.abi_length,
+ class_info.abi_length(),
)
.unwrap()
* versioned_constants.l2_resource_gas_costs.milligas_per_code_byte;
Expand Down
6 changes: 3 additions & 3 deletions crates/blockifier/src/fee/gas_usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::HashMap;
use crate::abi::constants;
use crate::context::{BlockContext, TransactionContext};
use crate::execution::call_info::{CallInfo, MessageL1CostInfo, OrderedEvent};
use crate::execution::contract_class::ClassInfo;
use crate::fee::eth_gas_constants;
use crate::fee::fee_utils::calculate_tx_gas_vector;
use crate::state::cached_state::StateChangesCount;
Expand All @@ -11,7 +12,6 @@ use crate::transaction::objects::{
GasVector, HasRelatedFeeType, ResourcesMapping, TransactionExecutionResult,
TransactionPreValidationResult,
};
use crate::transaction::transactions::ClassInfo;
use crate::utils::{u128_from_usize, usize_from_u128};
use crate::versioned_constants::VersionedConstants;

Expand Down Expand Up @@ -116,10 +116,10 @@ pub fn get_code_gas_cost(
) -> GasVector {
if let Some(class_info) = class_info {
let total_code_size = u128_from_usize(
(class_info.bytecode_length() + class_info.sierra_program_length)
(class_info.bytecode_length() + class_info.sierra_program_length())
// We assume each felt is a word.
* eth_gas_constants::WORD_WIDTH
+ class_info.abi_length,
+ class_info.abi_length(),
)
.expect("Failed to convert total code size from usize to u128.");
let l1_milligas =
Expand Down
3 changes: 2 additions & 1 deletion crates/blockifier/src/test_utils/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ use starknet_api::transaction::{
TransactionVersion,
};

use crate::execution::contract_class::ClassInfo;
use crate::test_utils::default_testing_resource_bounds;
use crate::transaction::account_transaction::AccountTransaction;
use crate::transaction::transactions::{ClassInfo, DeclareTransaction};
use crate::transaction::transactions::DeclareTransaction;

#[derive(Clone)]
pub struct DeclareTxArgs {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,7 @@ fn test_max_fee_limit_validate(
let grindy_validate_account = FeatureContract::AccountWithLongValidate(CairoVersion::Cairo0);
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(CairoVersion::Cairo0, grindy_validate_account.get_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 @@ -563,7 +562,7 @@ fn test_fail_declare(block_context: BlockContext, max_fee: Fee) {
};
state.set_contract_class(class_hash, contract_class.clone()).unwrap();
state.set_compiled_class_hash(class_hash, declare_tx.compiled_class_hash).unwrap();
let class_info = calculate_class_info_for_testing(CairoVersion::Cairo1, contract_class);
let class_info = calculate_class_info_for_testing(contract_class);
let declare_account_tx = AccountTransaction::Declare(
DeclareTransaction::new(
starknet_api::transaction::DeclareTransaction::V2(DeclareTransactionV2 {
Expand Down
21 changes: 7 additions & 14 deletions crates/blockifier/src/transaction/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ use starknet_api::transaction::{
use starknet_api::{calldata, class_hash, contract_address, patricia_key, stark_felt};
use strum::IntoEnumIterator;

use super::transactions::ClassInfo;
use crate::abi::abi_utils::{get_fee_token_var_address, get_storage_var_address};
use crate::context::{BlockContext, ChainInfo, FeeTokenAddresses};
use crate::execution::contract_class::{ContractClass, ContractClassV0};
use crate::execution::contract_class::{ClassInfo, ContractClass, ContractClassV0};
use crate::state::cached_state::CachedState;
use crate::state::state_api::State;
use crate::test_utils::contracts::FeatureContract;
Expand Down Expand Up @@ -252,10 +251,7 @@ pub fn create_account_tx_for_validate_test(
// It does not matter which class is declared for this test.
let declared_contract = FeatureContract::TestContract(CairoVersion::Cairo0);
let class_hash = declared_contract.get_class_hash();
let class_info = calculate_class_info_for_testing(
CairoVersion::Cairo0,
declared_contract.get_class(),
);
let class_info = calculate_class_info_for_testing(declared_contract.get_class());
declare_tx(
declare_tx_args! {
class_hash,
Expand Down Expand Up @@ -324,13 +320,10 @@ pub fn l1_resource_bounds(max_amount: u64, max_price: u128) -> ResourceBoundsMap
.unwrap()
}

pub fn calculate_class_info_for_testing(
cairo_version: CairoVersion,
contract_class: ContractClass,
) -> ClassInfo {
let sierra_program_length = match cairo_version {
CairoVersion::Cairo0 => 0,
CairoVersion::Cairo1 => 100,
pub fn calculate_class_info_for_testing(contract_class: ContractClass) -> ClassInfo {
let sierra_program_length = match contract_class {
ContractClass::V0(_) => 0,
ContractClass::V1(_) => 100,
};
ClassInfo { contract_class, sierra_program_length, abi_length: 100 }
ClassInfo::new(&contract_class, sierra_program_length, 100).unwrap()
}
2 changes: 1 addition & 1 deletion crates/blockifier/src/transaction/transaction_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use starknet_api::core::{calculate_contract_address, ContractAddress};
use starknet_api::transaction::{Fee, Transaction as StarknetApiTransaction, TransactionHash};

use super::transactions::ClassInfo;
use crate::context::BlockContext;
use crate::execution::contract_class::ClassInfo;
use crate::execution::entry_point::EntryPointExecutionContext;
use crate::fee::actual_cost::ActualCost;
use crate::state::cached_state::TransactionalState;
Expand Down
20 changes: 3 additions & 17 deletions crates/blockifier/src/transaction/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,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::ContractClass;
use crate::execution::contract_class::{ClassInfo, ContractClass};
use crate::execution::entry_point::{
CallEntryPoint, CallType, ConstructorContext, EntryPointExecutionContext,
};
Expand Down Expand Up @@ -103,20 +103,6 @@ pub trait ValidatableTransaction {
) -> TransactionExecutionResult<Option<CallInfo>>;
}

#[derive(Clone, Debug)]
// TODO(Ayelet,10/02/2024): Change to bytes.
pub struct ClassInfo {
pub contract_class: ContractClass,
pub sierra_program_length: usize,
pub abi_length: usize,
}

impl ClassInfo {
pub fn bytecode_length(&self) -> usize {
self.contract_class.bytecode_length()
}
}

#[derive(Debug)]
pub struct DeclareTransaction {
pub tx: starknet_api::transaction::DeclareTransaction,
Expand All @@ -134,7 +120,7 @@ impl DeclareTransaction {
only_query: bool,
) -> TransactionExecutionResult<Self> {
let declare_version = declare_tx.version();
verify_contract_class_version(&class_info.contract_class, declare_version)?;
verify_contract_class_version(&class_info.contract_class(), declare_version)?;
Ok(Self { tx: declare_tx, tx_hash, class_info, only_query })
}

Expand Down Expand Up @@ -165,7 +151,7 @@ impl DeclareTransaction {
}

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

pub fn only_query(&self) -> bool {
Expand Down
8 changes: 3 additions & 5 deletions crates/blockifier/src/transaction/transactions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,8 +788,7 @@ fn test_max_fee_exceeds_balance(account_cairo_version: CairoVersion) {

// Declare.
let contract_to_declare = FeatureContract::Empty(CairoVersion::Cairo0);
let class_info =
calculate_class_info_for_testing(CairoVersion::Cairo0, contract_to_declare.get_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 @@ -1079,8 +1078,7 @@ fn test_declare_tx(
let chain_info = &block_context.chain_info;
let state = &mut test_state(chain_info, BALANCE, &[(account, 1)]);
let class_hash = empty_contract.get_class_hash();
let class_info =
calculate_class_info_for_testing(account_cairo_version, empty_contract.get_class());
let class_info = calculate_class_info_for_testing(empty_contract.get_class());
let sender_address = account.get_instance_address(0);

let account_tx = declare_tx(
Expand Down Expand Up @@ -1171,7 +1169,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());
}

#[rstest]
Expand Down
2 changes: 2 additions & 0 deletions crates/native_blockifier/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use blockifier::execution::errors::ContractClassError;
use blockifier::state::errors::StateError;
use blockifier::transaction::errors::{
ParseError, TransactionExecutionError, TransactionPreValidationError,
Expand Down Expand Up @@ -59,6 +60,7 @@ macro_rules! native_blockifier_errors {
}

native_blockifier_errors!(
(ContractClassError, ContractClassError, PyContractClassError),
(NativeBlockifierInputError, NativeBlockifierInputError, PyNativeBlockifierInputError),
(ProgramError, ProgramError, PyProgramError),
(Pyo3Error, PyErr, PyPyo3Error),
Expand Down
21 changes: 11 additions & 10 deletions crates/native_blockifier/src/py_transaction.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::collections::BTreeMap;

use blockifier::execution::contract_class::{ContractClassV0, ContractClassV1};
use blockifier::execution::contract_class::{
ClassInfo, ContractClass, ContractClassV0, ContractClassV1,
};
use blockifier::transaction::account_transaction::AccountTransaction;
use blockifier::transaction::transaction_execution::Transaction;
use blockifier::transaction::transaction_types::TransactionType;
use blockifier::transaction::transactions::ClassInfo;
use cairo_vm::types::errors::program_errors::ProgramError;
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use starknet_api::transaction::{Resource, ResourceBounds};
Expand Down Expand Up @@ -152,8 +152,8 @@ impl PyClassInfo {
pub fn try_from(
py_class_info: PyClassInfo,
tx: &starknet_api::transaction::DeclareTransaction,
) -> Result<ClassInfo, ProgramError> {
let contract_class = match tx {
) -> NativeBlockifierResult<ClassInfo> {
let contract_class: ContractClass = match tx {
starknet_api::transaction::DeclareTransaction::V0(_)
| starknet_api::transaction::DeclareTransaction::V1(_) => {
ContractClassV0::try_from_json_string(&py_class_info.raw_contract_class)?.into()
Expand All @@ -163,10 +163,11 @@ impl PyClassInfo {
ContractClassV1::try_from_json_string(&py_class_info.raw_contract_class)?.into()
}
};
Ok(ClassInfo {
contract_class,
sierra_program_length: py_class_info.sierra_program_length,
abi_length: py_class_info.abi_length,
})
let class_info = ClassInfo::new(
&contract_class,
py_class_info.sierra_program_length,
py_class_info.abi_length,
)?;
Ok(class_info)
}
}

0 comments on commit 89f27e6

Please sign in to comment.