Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b55a950
Add `get_current_step`
franciszekjob Oct 23, 2025
8a8a80f
Minor refactor
franciszekjob Oct 23, 2025
073c95f
Fix scarb formatting
franciszekjob Oct 23, 2025
77dd8b9
Add test
franciszekjob Oct 23, 2025
5672903
Update changelog
franciszekjob Oct 23, 2025
53494da
Ignore cheats test of `meta_tx_v0` on `cairo-native`
MKowalski8 Oct 24, 2025
5dd5177
Additional check native test
MKowalski8 Oct 24, 2025
ab287a4
Enable test on vm
MKowalski8 Oct 24, 2025
d3ceb43
Merge branch 'fix-native-meta-tx-v0-tests' into 3824-get-current-step
franciszekjob Oct 24, 2025
7af1256
Merge branch 'master' of https://github.com/foundry-rs/starknet-found…
franciszekjob Oct 28, 2025
feed6d5
Apply code review suggestions
franciszekjob Oct 28, 2025
2afa790
Fix linting
franciszekjob Oct 28, 2025
9b7e7a2
Merge branch '3824-get-current-step' of https://github.com/foundry-rs…
franciszekjob Oct 28, 2025
30d1404
Fix lock
franciszekjob Oct 28, 2025
b5c1de0
WIP
franciszekjob Nov 3, 2025
57deb3b
Fix resources calculation
franciszekjob Nov 4, 2025
a674c9d
Remove print
franciszekjob Nov 4, 2025
8b22af2
Refactor
franciszekjob Nov 4, 2025
7254799
Little refactor
franciszekjob Nov 4, 2025
86b73b0
Remove unused file
franciszekjob Nov 4, 2025
660ec59
Refactor names
franciszekjob Nov 4, 2025
65c6297
Rename `vm_steps_total` -> `total_steps`
franciszekjob Nov 4, 2025
c691cb1
Apply code review suggestions
franciszekjob Nov 5, 2025
113bc5f
Apply code review suggestions
franciszekjob Nov 5, 2025
cbdd37e
Apply code review suggestions
franciszekjob Nov 6, 2025
d84fe26
Rename test
franciszekjob Nov 6, 2025
e4b5c13
Merge branch 'master' of https://github.com/foundry-rs/starknet-found…
franciszekjob Nov 6, 2025
b94c072
Fix imports
franciszekjob Nov 6, 2025
3a999a8
Remove comments
franciszekjob Nov 6, 2025
48c9e68
Add comment
franciszekjob Nov 6, 2025
7f6a893
Change variable name
franciszekjob Nov 7, 2025
195544a
Add assertions for specific step values in `test_get_current_vm_step`
franciszekjob Nov 10, 2025
ec48ca9
Fix import
franciszekjob Nov 10, 2025
4aab58a
Fix test
franciszekjob Nov 10, 2025
d17f252
Improve test for `get_current_vm_step`
franciszekjob Nov 10, 2025
d37a05b
Fix test
franciszekjob Nov 10, 2025
13f1af4
Reduce explanation
franciszekjob Nov 10, 2025
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Forge

#### Added

- `get_current_step` function to get the current step from Cairo VM during test execution. For more see [docs](https://foundry-rs.github.io/starknet-foundry/snforge-library/testing/get_current_step.html)

#### Changed

- Gas values in fuzzing test output are now displayed as whole numbers without fractional parts
Expand Down
16 changes: 8 additions & 8 deletions 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
@@ -1,3 +1,4 @@
use cairo_vm::vm::vm_core::VirtualMachine;
use config::RawForgeConfig;
use conversions::serde::deserialize::BufferReader;
use runtime::{CheatcodeHandlingResult, EnhancedHintError, ExtensionLogic, StarknetRuntime};
Expand All @@ -17,6 +18,7 @@ impl<'a> ExtensionLogic for ForgeConfigExtension<'a> {
selector: &str,
mut input_reader: BufferReader<'_>,
_extended_runtime: &mut Self::Runtime,
_vm: &mut VirtualMachine,
) -> Result<CheatcodeHandlingResult, EnhancedHintError> {
macro_rules! config_cheatcode {
( $prop:ident) => {{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ impl<'a> ExtensionLogic for ForgeExtension<'a> {
selector: &str,
mut input_reader: BufferReader<'_>,
extended_runtime: &mut Self::Runtime,
vm: &mut VirtualMachine,
) -> Result<CheatcodeHandlingResult, EnhancedHintError> {
if let Some(oracle_selector) = self
.oracle_hint_service
Expand Down Expand Up @@ -552,6 +553,14 @@ impl<'a> ExtensionLogic for ForgeExtension<'a> {
.cheat_block_hash(block_number, operation);
Ok(CheatcodeHandlingResult::from_serializable(()))
}
"get_current_step" => {
let current_step: u32 = vm
.get_current_step()
.try_into()
.context("Current step value exceeds u32")?;

Ok(CheatcodeHandlingResult::from_serializable(current_step))
}
_ => Ok(CheatcodeHandlingResult::Forwarded),
}
}
Expand Down
22 changes: 22 additions & 0 deletions crates/forge/tests/data/contracts/meta_tx_v0_checkers.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,25 @@ mod CheatBlockHashCheckerMetaTxV0 {
}
}
}

#[starknet::interface]
trait ISimpleCheckerMetaTxV0<TContractState> {
fn __execute__(ref self: TContractState) -> felt252;
}

#[starknet::contract(account)]
mod SimpleCheckerMetaTxV0 {
use starknet::SyscallResultTrait;
use starknet::syscalls::get_block_hash_syscall;

#[storage]
struct Storage {}

#[abi(embed_v0)]
impl ISimpleCheckerMetaTxV0 of super::ISimpleCheckerMetaTxV0<ContractState> {
fn __execute__(ref self: ContractState) -> felt252 {
1234567890.into()
}
}
}

39 changes: 39 additions & 0 deletions crates/forge/tests/integration/get_current_step.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use forge_runner::forge_config::ForgeTrackedResource;
use indoc::indoc;
use std::path::Path;
use test_utils::runner::{Contract, assert_passed};
use test_utils::running_tests::run_test_case;
use test_utils::test_case;

#[test]
fn test_get_current_step() {
let test = test_case!(
indoc!(
r#"
use snforge_std::testing::get_current_step;
use snforge_std::{ContractClassTrait, DeclareResultTrait, declare};

#[test]
fn check_current_step() {
let step_start = get_current_step();

let contract = declare("HelloStarknet").unwrap().contract_class().clone();
let _ = contract.deploy(@ArrayTrait::new()).unwrap();

let step_end = get_current_step();

assert!(step_end > step_start);
}
"#
),
Contract::from_code_path(
"HelloStarknet".to_string(),
Path::new("tests/data/contracts/hello_starknet.cairo"),
)
.unwrap()
);

let result = run_test_case(&test, ForgeTrackedResource::SierraGas);

assert_passed(&result);
}
65 changes: 65 additions & 0 deletions crates/forge/tests/integration/meta_tx_v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,67 @@ fn skip_scarb_lt_2_11_0() -> bool {
}
}

#[test]
fn check_meta_tx_v0_syscall_work_without_cheats() {
// TODO(#3704) Remove scarb version check
if skip_scarb_lt_2_11_0() {
return;
}

let test = test_case!(
indoc!(
r#"
use result::ResultTrait;
use array::ArrayTrait;
use option::OptionTrait;
use traits::TryInto;
use starknet::ContractAddress;
use snforge_std::{
declare, ContractClassTrait, DeclareResultTrait
};

#[starknet::interface]
trait IMetaTxV0Test<TContractState> {
fn execute_meta_tx_v0(
ref self: TContractState,
target: starknet::ContractAddress,
signature: Span<felt252>,
) -> felt252;
}

#[test]
fn test_meta_tx_v0_verify_tx_context_modification() {
let checker_contract = declare("SimpleCheckerMetaTxV0").unwrap().contract_class();
let (checker_address, _) = checker_contract.deploy(@ArrayTrait::new()).unwrap();

let meta_contract = declare("MetaTxV0Test").unwrap().contract_class();
let (meta_address, _) = meta_contract.deploy(@ArrayTrait::new()).unwrap();
let meta_dispatcher = IMetaTxV0TestDispatcher { contract_address: meta_address };

let mut signature = ArrayTrait::new();

let result = meta_dispatcher.execute_meta_tx_v0(checker_address, signature.span());

assert(result == 1234567890, 'Result should be 1234567890');
}
"#
),
Contract::from_code_path(
"SimpleCheckerMetaTxV0".to_string(),
Path::new("tests/data/contracts/meta_tx_v0_checkers.cairo"),
)
.unwrap(),
Contract::from_code_path(
"MetaTxV0Test".to_string(),
Path::new("tests/data/contracts/meta_tx_v0_test.cairo"),
)
.unwrap()
);

let result = run_test_case(&test, ForgeTrackedResource::SierraGas);
assert_passed(&result);
}

#[test]
fn meta_tx_v0_with_cheat_caller_address() {
// TODO(#3704) Remove scarb version check
Expand Down Expand Up @@ -95,6 +156,10 @@ fn meta_tx_v0_with_cheat_caller_address() {
assert_passed(&result);
}

#[cfg_attr(
feature = "cairo-native",
ignore = "Cheats in `meta_tx_v0` are not supported on `cairo-native`"
)]
#[test]
fn meta_tx_v0_with_cheat_block_hash() {
// TODO(#3704) Remove scarb version check
Expand Down
1 change: 1 addition & 0 deletions crates/forge/tests/integration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod gas;
mod generate_random_felt;
mod get_available_gas;
mod get_class_hash;
mod get_current_step;
mod interact_with_state;
mod l1_handler_executor;
mod message_to_l1;
Expand Down
2 changes: 2 additions & 0 deletions crates/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ impl<Extension: ExtensionLogic> ExtendedRuntime<Extension> {
&selector,
BufferReader::new(&inputs),
&mut self.extended_runtime,
vm,
);

let res = match result {
Expand Down Expand Up @@ -423,6 +424,7 @@ pub trait ExtensionLogic {
_selector: &str,
_input_reader: BufferReader,
_extended_runtime: &mut Self::Runtime,
_vm: &mut VirtualMachine,
) -> Result<CheatcodeHandlingResult, EnhancedHintError> {
Ok(CheatcodeHandlingResult::Forwarded)
}
Expand Down
1 change: 1 addition & 0 deletions crates/sncast/src/starknet_commands/script/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ impl<'a> ExtensionLogic for CastScriptExtension<'a> {
selector: &str,
mut input_reader: BufferReader,
_extended_runtime: &mut Self::Runtime,
_vm: &mut VirtualMachine,
) -> Result<CheatcodeHandlingResult, EnhancedHintError> {
match selector {
"call" => {
Expand Down
12 changes: 12 additions & 0 deletions docs/listings/testing_reference/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "testing_reference"
version = "0.1.0"
edition = "2024_07"

[dependencies]
starknet = "2.12.0"

[dev-dependencies]
snforge_std = { path = "../../../snforge_std" }

[[target.starknet-contract]]
27 changes: 27 additions & 0 deletions docs/listings/testing_reference/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#[starknet::interface]
pub trait ICounter<TContractState> {
fn increment(ref self: TContractState);
}

#[starknet::contract]
pub mod Counter {
use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};

#[storage]
struct Storage {
i: felt252,
}

#[constructor]
fn constructor(ref self: ContractState) {
self.i.write(0);
}

#[abi(embed_v0)]
impl CounterImpl of super::ICounter<ContractState> {
fn increment(ref self: ContractState) {
let current_value = self.i.read();
self.i.write(current_value + 1);
}
}
}
30 changes: 30 additions & 0 deletions docs/listings/testing_reference/tests/tests.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use snforge_std::testing::get_current_step;
use snforge_std::{ContractClassTrait, DeclareResultTrait, declare};
use testing_reference::{ICounterSafeDispatcher, ICounterSafeDispatcherTrait};

#[feature("safe_dispatcher")]
fn setup() {
// Deploy contract
let (contract_address, _) = declare("Counter")
.unwrap()
.contract_class()
.deploy(@array![])
.unwrap();

let dispatcher = ICounterSafeDispatcher { contract_address };

// Increment counter a few times
dispatcher.increment();
dispatcher.increment();
dispatcher.increment();
}

#[test]
fn test_setup_steps() {
let steps_start = get_current_step();
setup();
let steps_end = get_current_step();

// Assert that setup used no more than 100 steps
assert!(steps_end - steps_start <= 100);
}
2 changes: 2 additions & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@
* [env](appendix/snforge-library/env.md)
* [signature](appendix/snforge-library/signature.md)
* [fuzzable](appendix/snforge-library/fuzzable.md)
* [testing](appendix/snforge-library/testing.md)
* [get_current_step](appendix/snforge-library/testing/get_current_step.md)
* [`sncast` Commands](appendix/sncast.md)
* [common flags](appendix/sncast/common.md)
* [account](appendix/sncast/account/account.md)
Expand Down
7 changes: 7 additions & 0 deletions docs/src/appendix/snforge-library/testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# `testing` Module

Module containing functions useful for testing.

## Functions

* [`get_current_step`](./testing/get_current_step.md)
Loading
Loading