diff --git a/corelib/src/starknet/syscalls.cairo b/corelib/src/starknet/syscalls.cairo index c79148e5ae0..e686a1730e3 100644 --- a/corelib/src/starknet/syscalls.cairo +++ b/corelib/src/starknet/syscalls.cairo @@ -100,6 +100,17 @@ pub extern fn get_execution_info_v2_syscall() -> SyscallResult< Box, > implicits(GasBuiltin, System) nopanic; +/// Gets information about the current execution, version 3. +/// This syscall should not be called directly. Instead, use +/// `starknet::info::get_execution_info`. +/// +/// # Returns +/// +/// * A box containing the current V3 execution information. +pub extern fn get_execution_info_v3_syscall() -> SyscallResult< + Box, +> implicits(GasBuiltin, System) nopanic; + /// Calls the requested function in any previously declared class. /// /// # Arguments diff --git a/crates/cairo-lang-runner/src/casm_run/mod.rs b/crates/cairo-lang-runner/src/casm_run/mod.rs index c6fd480548f..110bc457ea2 100644 --- a/crates/cairo-lang-runner/src/casm_run/mod.rs +++ b/crates/cairo-lang-runner/src/casm_run/mod.rs @@ -212,6 +212,7 @@ struct TxInfo { nonce_data_availability_mode: Felt252, fee_data_availability_mode: Felt252, account_deployment_data: Vec, + proof_facts: Vec, } /// Copy of the Cairo `ResourceBounds` struct. @@ -935,6 +936,9 @@ impl CairoHintProcessor<'_> { let account_deployment_data_start = res_segment.ptr; res_segment.write_data(tx_info.account_deployment_data.iter().cloned())?; let account_deployment_data_end = res_segment.ptr; + let proof_facts_start = res_segment.ptr; + res_segment.write_data(tx_info.proof_facts.iter().cloned())?; + let proof_facts_end = res_segment.ptr; let tx_info_ptr = res_segment.ptr; res_segment.write(tx_info.version)?; res_segment.write(tx_info.account_contract_address)?; @@ -953,6 +957,8 @@ impl CairoHintProcessor<'_> { res_segment.write(tx_info.fee_data_availability_mode)?; res_segment.write(account_deployment_data_start)?; res_segment.write(account_deployment_data_end)?; + res_segment.write(proof_facts_start)?; + res_segment.write(proof_facts_end)?; let block_info_ptr = res_segment.ptr; res_segment.write(block_info.block_number)?; res_segment.write(block_info.block_timestamp)?; diff --git a/crates/cairo-lang-sierra-ap-change/src/core_libfunc_ap_change.rs b/crates/cairo-lang-sierra-ap-change/src/core_libfunc_ap_change.rs index d506e76269d..813e7f968f2 100644 --- a/crates/cairo-lang-sierra-ap-change/src/core_libfunc_ap_change.rs +++ b/crates/cairo-lang-sierra-ap-change/src/core_libfunc_ap_change.rs @@ -340,6 +340,7 @@ pub fn core_libfunc_ap_change( | StarknetConcreteLibfunc::GetBlockHash(_) | StarknetConcreteLibfunc::GetExecutionInfo(_) | StarknetConcreteLibfunc::GetExecutionInfoV2(_) + | StarknetConcreteLibfunc::GetExecutionInfoV3(_) | StarknetConcreteLibfunc::Deploy(_) | StarknetConcreteLibfunc::Keccak(_) | StarknetConcreteLibfunc::Sha256ProcessBlock(_) diff --git a/crates/cairo-lang-sierra-gas/src/starknet_libfunc_cost_base.rs b/crates/cairo-lang-sierra-gas/src/starknet_libfunc_cost_base.rs index 0914b844e5d..9c44475ef95 100644 --- a/crates/cairo-lang-sierra-gas/src/starknet_libfunc_cost_base.rs +++ b/crates/cairo-lang-sierra-gas/src/starknet_libfunc_cost_base.rs @@ -42,7 +42,8 @@ pub fn starknet_libfunc_cost_base(libfunc: &StarknetConcreteLibfunc) -> Vec syscall_cost(4), StarknetConcreteLibfunc::GetBlockHash(_) => syscall_cost(1), StarknetConcreteLibfunc::GetExecutionInfo(_) - | StarknetConcreteLibfunc::GetExecutionInfoV2(_) => syscall_cost(0), + | StarknetConcreteLibfunc::GetExecutionInfoV2(_) + | StarknetConcreteLibfunc::GetExecutionInfoV3(_) => syscall_cost(0), StarknetConcreteLibfunc::Deploy(_) => syscall_cost(5), StarknetConcreteLibfunc::Keccak(_) => syscall_cost(2), StarknetConcreteLibfunc::Sha256ProcessBlock(_) => syscall_cost(2), diff --git a/crates/cairo-lang-sierra-to-casm/src/invocations/starknet/mod.rs b/crates/cairo-lang-sierra-to-casm/src/invocations/starknet/mod.rs index 446b4ed66b8..90830b45f7c 100644 --- a/crates/cairo-lang-sierra-to-casm/src/invocations/starknet/mod.rs +++ b/crates/cairo-lang-sierra-to-casm/src/invocations/starknet/mod.rs @@ -60,7 +60,8 @@ pub fn build( build_syscalls(builder, "GetBlockHash", [1], [1]) } StarknetConcreteLibfunc::GetExecutionInfo(_) - | StarknetConcreteLibfunc::GetExecutionInfoV2(_) => { + | StarknetConcreteLibfunc::GetExecutionInfoV2(_) + | StarknetConcreteLibfunc::GetExecutionInfoV3(_) => { build_syscalls(builder, "GetExecutionInfo", [], [1]) } StarknetConcreteLibfunc::Deploy(_) => { diff --git a/crates/cairo-lang-sierra/src/extensions/modules/starknet/getter.rs b/crates/cairo-lang-sierra/src/extensions/modules/starknet/getter.rs index 3defe6b1206..4688c5682c7 100644 --- a/crates/cairo-lang-sierra/src/extensions/modules/starknet/getter.rs +++ b/crates/cairo-lang-sierra/src/extensions/modules/starknet/getter.rs @@ -111,6 +111,32 @@ fn get_execution_info_v2_type( ) } +/// Helper for v3::ExecutionInfo type. +fn get_execution_info_v3_type( + context: &dyn SignatureSpecializationContext, +) -> Result { + let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?; + let contract_address_ty = context.get_concrete_type(ContractAddressType::id(), &[])?; + context.get_concrete_type( + StructType::id(), + &[ + GenericArg::UserType(UserTypeId::from_string( + "core::starknet::info::v3::ExecutionInfo", + )), + // block_info + GenericArg::Type(box_ty(context, get_block_info_type(context)?)?), + // tx_info + GenericArg::Type(box_ty(context, get_tx_info_v3_type(context)?)?), + // caller_address + GenericArg::Type(contract_address_ty.clone()), + // contract_address + GenericArg::Type(contract_address_ty), + // entry_point_selector + GenericArg::Type(felt252_ty), + ], + ) +} + /// Helper for BlockInfo type. fn get_block_info_type( context: &dyn SignatureSpecializationContext, @@ -234,6 +260,51 @@ fn get_tx_info_v2_type( ) } +/// Helper for v3::TxInfo type. +fn get_tx_info_v3_type( + context: &dyn SignatureSpecializationContext, +) -> Result { + let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?; + let felt252_span_ty = felt252_span_ty(context)?; + let contract_address_ty = context.get_concrete_type(ContractAddressType::id(), &[])?; + let u32_ty = context.get_concrete_type(Uint32Type::id(), &[])?; + let u128_ty = context.get_concrete_type(Uint128Type::id(), &[])?; + context.get_concrete_type( + StructType::id(), + &[ + GenericArg::UserType(UserTypeId::from_string("core::starknet::info::v3::TxInfo")), + // version + GenericArg::Type(felt252_ty.clone()), + // account_contract_address + GenericArg::Type(contract_address_ty), + // max_fee + GenericArg::Type(u128_ty.clone()), + // signature + GenericArg::Type(felt252_span_ty.clone()), + // transaction_hash + GenericArg::Type(felt252_ty.clone()), + // chain_id + GenericArg::Type(felt252_ty.clone()), + // nonce + GenericArg::Type(felt252_ty), + // resource_bounds + GenericArg::Type(resource_bounds_span_ty(context)?), + // tip + GenericArg::Type(u128_ty), + // paymaster_data + GenericArg::Type(felt252_span_ty.clone()), + // nonce_data_availability_mode + GenericArg::Type(u32_ty.clone()), + // fee_data_availability_mode + GenericArg::Type(u32_ty), + // account_deployment_data + GenericArg::Type(felt252_span_ty.clone()), + // proof_facts + GenericArg::Type(felt252_span_ty), + ], + ) +} + #[derive(Default)] pub struct GetExecutionInfoTrait {} impl GetterTraitsEx for GetExecutionInfoTrait { @@ -257,3 +328,15 @@ impl GetterTraitsEx for GetExecutionInfoV2Trait { box_ty(context, get_execution_info_v2_type(context)?) } } + +#[derive(Default)] +pub struct GetExecutionInfoV3Trait {} +impl GetterTraitsEx for GetExecutionInfoV3Trait { + const STR_ID: &'static str = "get_execution_info_v3_syscall"; + + fn info_type_id( + context: &dyn SignatureSpecializationContext, + ) -> Result { + box_ty(context, get_execution_info_v3_type(context)?) + } +} diff --git a/crates/cairo-lang-sierra/src/extensions/modules/starknet/mod.rs b/crates/cairo-lang-sierra/src/extensions/modules/starknet/mod.rs index e685e7614f4..0a9cf240fd8 100644 --- a/crates/cairo-lang-sierra/src/extensions/modules/starknet/mod.rs +++ b/crates/cairo-lang-sierra/src/extensions/modules/starknet/mod.rs @@ -1,4 +1,5 @@ use crate::extensions::lib_func::SignatureSpecializationContext; +use crate::extensions::starknet::getter::GetExecutionInfoV3Trait; use crate::extensions::{NamedType, SpecializationError}; use crate::ids::{ConcreteTypeId, UserTypeId}; use crate::program::GenericArg; @@ -85,6 +86,7 @@ define_libfunc_hierarchy! { GetBlockHash(GetBlockHashLibfunc), GetExecutionInfo(GetterLibfunc), GetExecutionInfoV2(GetterLibfunc), + GetExecutionInfoV3(GetterLibfunc), Deploy(DeployLibfunc), Keccak(KeccakLibfunc), Sha256ProcessBlock(Sha256ProcessBlockLibfunc), diff --git a/crates/cairo-lang-starknet-classes/src/allowed_libfuncs_lists/all.json b/crates/cairo-lang-starknet-classes/src/allowed_libfuncs_lists/all.json index 700c188930a..243c6e1b836 100644 --- a/crates/cairo-lang-starknet-classes/src/allowed_libfuncs_lists/all.json +++ b/crates/cairo-lang-starknet-classes/src/allowed_libfuncs_lists/all.json @@ -97,6 +97,7 @@ "get_class_hash_at_syscall", "get_execution_info_syscall", "get_execution_info_v2_syscall", + "get_execution_info_v3_syscall", "hades_permutation", "i128_const", "i128_diff", diff --git a/tests/e2e_test_data/libfuncs/starknet/syscalls b/tests/e2e_test_data/libfuncs/starknet/syscalls index 477ad2e7bcf..f766aad5c79 100644 --- a/tests/e2e_test_data/libfuncs/starknet/syscalls +++ b/tests/e2e_test_data/libfuncs/starknet/syscalls @@ -344,6 +344,99 @@ test::foo@F0([0]: GasBuiltin, [1]: System) -> (GasBuiltin, System, core::result: //! > ========================================================================== +//! > get_execution_info_v3_syscall libfunc + +//! > test_comments + +//! > test_runner_name +SmallE2ETestRunner + +//! > cairo_code +fn foo() -> starknet::SyscallResult> { + starknet::syscalls::get_execution_info_v3_syscall() +} + +//! > casm +[ap + 0] = 94901967946959054011942058057773508207, ap++; +[ap + -1] = [[fp + -3] + 0]; +[fp + -4] = [[fp + -3] + 1]; +%{ syscall_handler.syscall(syscall_ptr=memory[fp + -3]) %} +[ap + 0] = [[fp + -3] + 3], ap++; +jmp rel 12 if [ap + -1] != 0; +[ap + 0] = [[fp + -3] + 2], ap++; +[ap + 0] = [ap + -1], ap++; +[ap + 0] = [fp + -3] + 5, ap++; +[ap + 0] = 0, ap++; +[ap + 0] = 0, ap++; +[ap + 0] = [[fp + -3] + 4], ap++; +ret; +[ap + 0] = [[fp + -3] + 2], ap++; +[ap + 0] = [ap + -1], ap++; +[ap + 0] = [fp + -3] + 6, ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [[fp + -3] + 4], ap++; +[ap + 0] = [[fp + -3] + 5], ap++; +ret; + +//! > function_costs +test::foo: SmallOrderedMap({Const: 11100}) + +//! > sierra_code +type GasBuiltin = GasBuiltin [storable: true, drop: false, dup: false, zero_sized: false]; +type Box = Box [storable: true, drop: true, dup: true, zero_sized: false]; +type Array = Array [storable: true, drop: true, dup: false, zero_sized: false]; +type core::result::Result::, core::array::Array::> = Enum, core::array::Array::>, Box, Array> [storable: true, drop: true, dup: false, zero_sized: false]; +type felt252 = felt252 [storable: true, drop: true, dup: true, zero_sized: false]; +type Box = Box [storable: true, drop: true, dup: true, zero_sized: false]; +type Box = Box [storable: true, drop: true, dup: true, zero_sized: false]; +type ContractAddress = ContractAddress [storable: true, drop: true, dup: true, zero_sized: false]; +type core::starknet::info::v3::ExecutionInfo = Struct, Box, ContractAddress, ContractAddress, felt252> [storable: true, drop: true, dup: true, zero_sized: false]; +type u128 = u128 [storable: true, drop: true, dup: true, zero_sized: false]; +type Snapshot> = Snapshot> [storable: true, drop: true, dup: true, zero_sized: false]; +type core::array::Span:: = Struct, Snapshot>> [storable: true, drop: true, dup: true, zero_sized: false]; +type Array = Array [storable: true, drop: true, dup: false, zero_sized: false]; +type Snapshot> = Snapshot> [storable: true, drop: true, dup: true, zero_sized: false]; +type core::array::Span:: = Struct, Snapshot>> [storable: true, drop: true, dup: true, zero_sized: false]; +type u32 = u32 [storable: true, drop: true, dup: true, zero_sized: false]; +type core::starknet::info::v3::TxInfo = Struct, felt252, felt252, felt252, core::array::Span::, u128, core::array::Span::, u32, u32, core::array::Span::, core::array::Span::> [storable: true, drop: true, dup: true, zero_sized: false]; +type u64 = u64 [storable: true, drop: true, dup: true, zero_sized: false]; +type core::starknet::info::BlockInfo = Struct [storable: true, drop: true, dup: true, zero_sized: false]; +type core::starknet::info::v2::ResourceBounds = Struct [storable: true, drop: true, dup: true, zero_sized: false]; +type System = System [storable: true, drop: false, dup: false, zero_sized: false]; + +libfunc get_execution_info_v3_syscall = get_execution_info_v3_syscall; +libfunc branch_align = branch_align; +libfunc store_temp = store_temp; +libfunc redeposit_gas = redeposit_gas; +libfunc enum_init, core::array::Array::>, 0> = enum_init, core::array::Array::>, 0>; +libfunc store_temp = store_temp; +libfunc store_temp, core::array::Array::>> = store_temp, core::array::Array::>>; +libfunc enum_init, core::array::Array::>, 1> = enum_init, core::array::Array::>, 1>; + +F0: +get_execution_info_v3_syscall([0], [1]) { fallthrough([2], [3], [4]) F0_B0([5], [6], [7]) }; +branch_align() -> (); +store_temp([2]) -> ([2]); +redeposit_gas([2]) -> ([8]); +enum_init, core::array::Array::>, 0>([4]) -> ([9]); +store_temp([8]) -> ([8]); +store_temp([3]) -> ([3]); +store_temp, core::array::Array::>>([9]) -> ([9]); +return([8], [3], [9]); +F0_B0: +branch_align() -> (); +store_temp([5]) -> ([5]); +redeposit_gas([5]) -> ([10]); +enum_init, core::array::Array::>, 1>([7]) -> ([11]); +store_temp([10]) -> ([10]); +store_temp([6]) -> ([6]); +store_temp, core::array::Array::>>([11]) -> ([11]); +return([10], [6], [11]); + +test::foo@F0([0]: GasBuiltin, [1]: System) -> (GasBuiltin, System, core::result::Result::, core::array::Array::>); + +//! > ========================================================================== + //! > call_contract_syscall libfunc //! > test_comments