Skip to content

Commit

Permalink
test(blockifier): add builtins_test
Browse files Browse the repository at this point in the history
  • Loading branch information
Yonatan-Starkware committed Feb 2, 2025
1 parent a3d8940 commit 8161aa6
Show file tree
Hide file tree
Showing 10 changed files with 10,444 additions and 9,053 deletions.
2,957 changes: 1,977 additions & 980 deletions crates/blockifier/feature_contracts/cairo1/compiled/test_contract.casm.json

Large diffs are not rendered by default.

16,349 changes: 8,293 additions & 8,056 deletions crates/blockifier/feature_contracts/cairo1/sierra/test_contract.sierra.json

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions crates/blockifier/feature_contracts/cairo1/test_contract.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ mod TestContract {
EvalCircuitResult, EvalCircuitTrait, u384, CircuitOutputsTrait, CircuitModulus,
CircuitInputs, AddInputResultTrait
};
use core::hash::HashStateTrait;
use core::pedersen::PedersenTrait;
use core::poseidon::PoseidonTrait;

#[storage]
struct Storage {
Expand Down Expand Up @@ -735,4 +738,37 @@ mod TestContract {
#[external(v0)]
fn empty_function(ref self: ContractState) {
}

#[external(v0)]
fn test_bitwise(ref self: ContractState) {
let x: u32 = 0x1;
let y: u32 = 0x2;
let _z = x & y;
}

#[external(v0)]
fn test_pedersen (ref self: ContractState) {
let mut state = PedersenTrait::new(0);
state = state.update(1);
let _hash = state.finalize();
}

#[external(v0)]
fn test_poseidon (ref self: ContractState) {
let mut state = PoseidonTrait::new();
state = state.update(1);
let _hash = state.finalize();
}

#[external(v0)]
fn test_ecop (ref self: ContractState) {
let m: felt252 = 2;
let a: felt252 = 336742005567258698661916498343089167447076063081786685068305785816009957563;
let b: felt252 = 1706004133033694959518200210163451614294041810778629639790706933324248611779;
let p : ec::NonZeroEcPoint = (ec::ec_point_try_new_nz(a, b)).unwrap();
let mut s: ec::EcState = ec::ec_state_init();
ec::ec_state_add_mul(ref s, m, p);
}
}


Binary file added crates/blockifier/libcairo_native_runtime.a
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ fn test_block_info_syscalls(

#[rstest]
fn test_tx_info(#[values(false, true)] only_query: bool) {
use crate::context::{BlockContext, TransactionContext};

let test_contract = FeatureContract::TestContract(CairoVersion::Cairo0);
let mut state = test_state(&ChainInfo::create_for_testing(), Fee(0), &[(test_contract, 1)]);
let mut version = felt!(1_u8);
Expand All @@ -478,7 +480,7 @@ fn test_tx_info(#[values(false, true)] only_query: bool) {
calldata: expected_tx_info,
..trivial_external_entry_point_new(test_contract)
};
let tx_info = TransactionInfo::Deprecated(DeprecatedTransactionInfo {
let transaction_info = TransactionInfo::Deprecated(DeprecatedTransactionInfo {
common_fields: CommonAccountFields {
transaction_hash: tx_hash,
version: TransactionVersion::ONE,
Expand All @@ -490,10 +492,14 @@ fn test_tx_info(#[values(false, true)] only_query: bool) {
max_fee,
});
let limit_steps_by_resources = false; // Do not limit steps by resources as we use default reasources.
let tx_context = TransactionContext {
block_context: BlockContext::create_for_testing(),
tx_info: transaction_info,
};
let result = entry_point_call
.execute_directly_given_tx_info(
.execute_directly_given_tx_context(
&mut state,
tx_info,
tx_context,
limit_steps_by_resources,
ExecutionMode::Execute,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use rstest::rstest;
use rstest_reuse::apply;
use starknet_api::abi::abi_utils::selector_from_name;
use starknet_api::contract_class::SierraVersion;
use starknet_api::transaction::fields::Calldata;

use crate::context::{BlockContext, ChainInfo, TransactionContext};
use crate::execution::common_hints::ExecutionMode;
use crate::execution::entry_point::CallEntryPoint;
use crate::test_utils::contracts::FeatureContract;
use crate::test_utils::initial_test_state::test_state;
use crate::test_utils::test_templates::runnable_version;
use crate::test_utils::{trivial_external_entry_point_new, CairoVersion, RunnableCairo1, BALANCE};
use crate::transaction::objects::{CurrentTransactionInfo, TransactionInfo};
use crate::utils::u64_from_usize;
use crate::versioned_constants::VersionedConstants;

#[apply(runnable_version)]
#[case::pedersen("test_pedersen")]
#[case::bitwise("test_bitwise")]
#[case::ecop("test_ecop")]
#[case::poseidon("test_poseidon")]
// This test case tests the add_mod and mul_mod builtins.
#[case::add_and_mul_mod("test_circuit")]
fn builtins_test(runnable_version: RunnableCairo1, #[case] selector_name: &str) {
let test_contract = FeatureContract::TestContract(CairoVersion::Cairo1(runnable_version));
let chain_info = &ChainInfo::create_for_testing();
let mut state = test_state(chain_info, BALANCE, &[(test_contract, 1)]);

let calldata = Calldata(vec![].into());
let entry_point_call = CallEntryPoint {
entry_point_selector: selector_from_name(selector_name),
calldata,
..trivial_external_entry_point_new(test_contract)
};

let call_info_while_tracking_gas_consumed =
entry_point_call.clone().execute_directly(&mut state).unwrap();

let mut block_context = BlockContext::create_for_account_testing();
block_context.versioned_constants.min_sierra_version_for_sierra_gas =
SierraVersion::new(2, 8, 0);
let tx_info = TransactionInfo::Current(CurrentTransactionInfo::create_for_testing());
let tx_context = TransactionContext { block_context, tx_info };

let call_info_while_tracking_vm_resources = entry_point_call
.execute_directly_given_tx_context(&mut state, tx_context, false, ExecutionMode::Execute)
.unwrap();

let versioned_constants = VersionedConstants::latest_constants();
let gas_costs = versioned_constants.os_constants.gas_costs;
let execution_resources = call_info_while_tracking_vm_resources.resources;
let n_steps = u64_from_usize(execution_resources.n_steps);
let n_memory_holes = u64_from_usize(execution_resources.n_memory_holes);
let total_builtin_gas_cost: u64 = execution_resources
.builtin_instance_counter
.iter()
.map(|(builtin, amount)| {
let builtin_cost = gas_costs
.builtins
.get_builtin_gas_cost(builtin)
.unwrap_or_else(|err| panic!("Failed to get gas cost: {}", err));
builtin_cost * u64_from_usize(*amount)
})
.sum();
let gas_consumed_tracked_by_vm_resources = n_steps * gas_costs.base.step_gas_cost
+ n_memory_holes * gas_costs.base.memory_hole_gas_cost
+ total_builtin_gas_cost;

// I think it can be a good idea to leave here a comment explaining what is this difference.
let mut expected_difference = gas_costs.base.step_gas_cost;
if selector_name == "test_circuit" {
expected_difference -= gas_costs.base.memory_hole_gas_cost;
}

// TODO(Meshi): Remove this if statement when the bug cousing the difference in the gas_consumed
// of test_circuit using native will be fixed.
#[cfg(feature = "cairo_native")]
if selector_name == "test_circuit" && matches!(runnable_version, RunnableCairo1::Native) {
expected_difference = gas_consumed_tracked_by_vm_resources
- call_info_while_tracking_gas_consumed.execution.gas_consumed;
}

pretty_assertions::assert_eq!(
gas_consumed_tracked_by_vm_resources,
call_info_while_tracking_gas_consumed.execution.gas_consumed + expected_difference
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use starknet_api::{felt, nonce, tx_hash};
use starknet_types_core::felt::Felt;
use test_case::test_case;

use crate::context::ChainInfo;
use crate::context::{BlockContext, ChainInfo, TransactionContext};
use crate::execution::common_hints::ExecutionMode;
use crate::execution::entry_point::CallEntryPoint;
use crate::test_utils::contracts::FeatureContract;
Expand Down Expand Up @@ -242,7 +242,7 @@ fn test_get_execution_info(
};

let expected_tx_info: Vec<Felt>;
let tx_info: TransactionInfo;
let transaction_info: TransactionInfo;
if version == TransactionVersion::ONE {
expected_tx_info = vec![
version.0, /* Transaction
Expand All @@ -255,7 +255,7 @@ fn test_get_execution_info(
nonce.0, // Nonce.
];

tx_info = TransactionInfo::Deprecated(DeprecatedTransactionInfo {
transaction_info = TransactionInfo::Deprecated(DeprecatedTransactionInfo {
common_fields: CommonAccountFields {
transaction_hash: tx_hash,
version: TransactionVersion::ONE,
Expand All @@ -278,7 +278,7 @@ fn test_get_execution_info(
nonce.0, // Nonce.
];

tx_info = TransactionInfo::Current(CurrentTransactionInfo {
transaction_info = TransactionInfo::Current(CurrentTransactionInfo {
common_fields: CommonAccountFields {
transaction_hash: tx_hash,
version: TransactionVersion::THREE,
Expand Down Expand Up @@ -320,8 +320,16 @@ fn test_get_execution_info(
),
..trivial_external_entry_point_with_address(test_contract_address)
};
let result =
entry_point_call.execute_directly_given_tx_info(state, tx_info, false, execution_mode);
let tx_context = TransactionContext {
block_context: BlockContext::create_for_testing(),
tx_info: transaction_info,
};
let result = entry_point_call.execute_directly_given_tx_context(
state,
tx_context,
false,
execution_mode,
);

assert!(!result.unwrap().execution.failed);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod builtins_test;
mod call_contract;
mod constants;
mod deploy;
Expand Down
20 changes: 12 additions & 8 deletions crates/blockifier/src/test_utils/struct_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,24 @@ impl CallEntryPoint {
pub fn execute_directly(self, state: &mut dyn State) -> EntryPointExecutionResult<CallInfo> {
// Do not limit steps by resources as we use default resources.
let limit_steps_by_resources = false;
self.execute_directly_given_tx_info(
self.execute_directly_given_tx_context(
state,
TransactionInfo::Current(CurrentTransactionInfo::create_for_testing()),
TransactionContext {
block_context: BlockContext::create_for_testing(),
tx_info: TransactionInfo::Current(CurrentTransactionInfo::create_for_testing()),
},
limit_steps_by_resources,
ExecutionMode::Execute,
)
}

pub fn execute_directly_given_tx_info(
pub fn execute_directly_given_tx_context(
self,
state: &mut dyn State,
tx_info: TransactionInfo,
tx_context: TransactionContext,
limit_steps_by_resources: bool,
execution_mode: ExecutionMode,
) -> EntryPointExecutionResult<CallInfo> {
let tx_context =
TransactionContext { block_context: BlockContext::create_for_testing(), tx_info };
let mut context = EntryPointExecutionContext::new(
Arc::new(tx_context),
execution_mode,
Expand All @@ -89,10 +90,13 @@ impl CallEntryPoint {
state: &mut dyn State,
) -> EntryPointExecutionResult<CallInfo> {
let limit_steps_by_resources = false; // Do not limit steps by resources as we use default reasources.
self.execute_directly_given_tx_info(
self.execute_directly_given_tx_context(
state,
// TODO(Yoni, 1/12/2024): change the default to V3.
TransactionInfo::Deprecated(DeprecatedTransactionInfo::default()),
TransactionContext {
block_context: BlockContext::create_for_testing(),
tx_info: TransactionInfo::Deprecated(DeprecatedTransactionInfo::default()),
},
limit_steps_by_resources,
ExecutionMode::Validate,
)
Expand Down
14 changes: 14 additions & 0 deletions crates/blockifier/src/test_utils/test_templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ fn cairo_version(
) {
}

#[cfg(test)]
#[cfg(not(feature = "cairo_native"))]
#[template]
#[rstest]
fn runnable_version(#[values(RunnableCairo1::Casm)] runnable_version: RunnableCairo1) {}

#[cfg(feature = "cairo_native")]
#[template]
#[rstest]
fn runnable_version(
#[values(RunnableCairo1::Casm, RunnableCairo1::Native)] runnable_version: RunnableCairo1,
) {
}

#[cfg(not(feature = "cairo_native"))]
#[template]
#[rstest]
Expand Down

0 comments on commit 8161aa6

Please sign in to comment.