Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 1 addition & 2 deletions crates/forge-runner/src/running.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use anyhow::{Result, bail};
use blockifier::execution::call_info::CallInfo;
use blockifier::execution::contract_class::TrackedResource;
use blockifier::execution::entry_point::EntryPointExecutionContext;
use blockifier::execution::entry_point_execution::prepare_call_arguments;
use blockifier::execution::entry_point_execution::{prepare_call_arguments, run_entry_point};
use blockifier::execution::errors::EntryPointExecutionError;
use blockifier::state::cached_state::CachedState;
use cairo_vm::Felt252;
Expand Down Expand Up @@ -53,7 +53,6 @@ mod syscall_handler;
pub mod with_config;

use crate::debugging::{TraceVerbosity, build_debugging_trace};
use crate::running::copied_code::run_entry_point;
pub use hints::hints_to_params;
use setup::VmExecutionContext;
pub use syscall_handler::has_segment_arena;
Expand Down
3 changes: 1 addition & 2 deletions crates/forge-runner/src/running/config_run.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::hints::hints_by_representation;
use crate::running::copied_code::run_entry_point;
use crate::running::execution::finalize_execution;
use crate::running::setup::{
VmExecutionContext, build_test_call_and_entry_point, entry_point_initial_budget,
Expand All @@ -8,7 +7,7 @@ use crate::running::setup::{
use crate::{forge_config::ForgeTrackedResource, package_tests::TestDetails};
use anyhow::Result;
use blockifier::execution::contract_class::TrackedResource;
use blockifier::execution::entry_point_execution::prepare_call_arguments;
use blockifier::execution::entry_point_execution::{prepare_call_arguments, run_entry_point};
use blockifier::state::{cached_state::CachedState, state_api::StateReader};
use cheatnet::runtime_extensions::forge_config_extension::{
ForgeConfigExtension, config::RawForgeConfig,
Expand Down
176 changes: 6 additions & 170 deletions crates/forge-runner/src/running/copied_code.rs
Original file line number Diff line number Diff line change
@@ -1,178 +1,14 @@
// TODO(#3293) Remove this file once the copied code is upstreamed to blockifier.
//! Module containing copied code to be upstreamed to blockifier

use blockifier::blockifier_versioned_constants::GasCosts;
use blockifier::execution::contract_class::{EntryPointV1, TrackedResource};
use blockifier::execution::entry_point::EntryPointExecutionResult;
use blockifier::execution::contract_class::TrackedResource;
use blockifier::execution::entry_point_execution::CallResult;
use blockifier::execution::errors::{
EntryPointExecutionError, PostExecutionError, PreExecutionError,
};
use blockifier::execution::execution_utils::{
Args, ReadOnlySegments, read_execution_retdata, write_felt, write_maybe_relocatable,
};
use blockifier::execution::errors::PostExecutionError;
use blockifier::execution::execution_utils::read_execution_retdata;
use blockifier::execution::syscalls::hint_processor::SyscallHintProcessor;
use cairo_vm::hint_processor::hint_processor_definition::HintProcessor;
use cairo_vm::types::builtin_name::BuiltinName;
use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable};
use cairo_vm::vm::errors::cairo_run_errors::CairoRunError;
use cairo_vm::vm::errors::memory_errors::MemoryError;
use cairo_vm::vm::errors::vm_errors::VirtualMachineError;
use cairo_vm::vm::runners::builtin_runner::BuiltinRunner;
use cairo_vm::vm::runners::cairo_runner::{CairoArg, CairoRunner};
use cairo_vm::vm::security::verify_secure_runner;
use num_traits::{ToPrimitive, Zero};
use starknet_types_core::felt::Felt;

#[expect(clippy::needless_pass_by_value, clippy::result_large_err)]
// Reason copied: Signature change
/// Runs the runner from the given PC.
pub(crate) fn run_entry_point<HP: HintProcessor>(
runner: &mut CairoRunner,
// Modified code
// hint_processor: &mut SyscallHintProcessor<'_>,
hint_processor: &mut HP,
entry_point: EntryPointV1,
args: Args,
program_segment_size: usize,
) -> EntryPointExecutionResult<()> {
// Note that we run `verify_secure_runner` manually after filling the holes in the rc96 segment.
let verify_secure = false;
let args: Vec<&CairoArg> = args.iter().collect();
runner.run_from_entrypoint(
entry_point.pc(),
&args,
verify_secure,
Some(program_segment_size),
hint_processor,
)?;

maybe_fill_holes(entry_point, runner)?;

verify_secure_runner(runner, false, Some(program_segment_size))
.map_err(CairoRunError::VirtualMachine)?;

Ok(())
}

#[expect(
clippy::items_after_statements,
clippy::needless_pass_by_value,
clippy::result_large_err
)]
// Reason copied: Required by `run_entry_point`
/// Fills the holes after running the entry point.
/// Currently only fills the holes in the rc96 segment.
fn maybe_fill_holes(
entry_point: EntryPointV1,
runner: &mut CairoRunner,
) -> Result<(), EntryPointExecutionError> {
let Some(rc96_offset) = entry_point
.builtins
.iter()
.rev()
.position(|name| *name == BuiltinName::range_check96)
else {
return Ok(());
};
let rc96_builtin_runner = runner
.vm
.get_builtin_runners()
.iter()
.find_map(|builtin| {
if let BuiltinRunner::RangeCheck96(rc96_builtin_runner) = builtin {
Some(rc96_builtin_runner)
} else {
None
}
})
.expect("RangeCheck96 builtin runner not found.");

// 'EntryPointReturnValues' is returned after the implicits and its size is 5,
// So the last implicit is at offset 5 + 1.
const IMPLICITS_OFFSET: usize = 6;
let rc_96_stop_ptr = (runner.vm.get_ap() - (IMPLICITS_OFFSET + rc96_offset))
.map_err(|err| CairoRunError::VirtualMachine(VirtualMachineError::Math(err)))?;

let rc96_base = rc96_builtin_runner.base();
let rc96_segment: isize = rc96_base
.try_into()
.expect("Builtin segment index must fit in isize.");

let Relocatable {
segment_index: rc96_stop_segment,
offset: stop_offset,
} = runner
.vm
.get_relocatable(rc_96_stop_ptr)
.map_err(CairoRunError::MemoryError)?;
assert_eq!(rc96_stop_segment, rc96_segment);

// Update `segment_used_sizes` to include the holes.
runner
.vm
.segments
.segment_used_sizes
.as_mut()
.expect("Segments used sizes should be calculated at this point")[rc96_base] = stop_offset;

for offset in 0..stop_offset {
match runner.vm.insert_value(
Relocatable {
segment_index: rc96_segment,
offset,
},
Felt::zero(),
) {
// If the value is already set, ignore the error.
Ok(()) | Err(MemoryError::InconsistentMemory(_)) => {}
Err(err) => panic!("Unexpected error when filling holes: {err}."),
}
}

Ok(())
}

// Reason copied: Private function
pub(crate) fn prepare_program_extra_data(
runner: &mut CairoRunner,
// contract_class: &CompiledClassV1,
bytecode_length: usize,
read_only_segments: &mut ReadOnlySegments,
gas_costs: &GasCosts,
) -> Result<usize, PreExecutionError> {
// Create the builtin cost segment, the builtin order should be the same as the price builtin
// array in the os in compiled_class.cairo in load_compiled_class_facts.
let builtin_price_array = [
gas_costs.builtins.pedersen,
gas_costs.builtins.bitwise,
gas_costs.builtins.ecop,
gas_costs.builtins.poseidon,
gas_costs.builtins.add_mod,
gas_costs.builtins.mul_mod,
];

let data = builtin_price_array
.iter()
.map(|&x| MaybeRelocatable::from(Felt::from(x)))
.collect::<Vec<_>>();
let builtin_cost_segment_start = read_only_segments.allocate(&mut runner.vm, &data)?;

// Put a pointer to the builtin cost segment at the end of the program (after the
// additional `ret` statement).
let mut ptr = (runner.vm.get_pc() + bytecode_length)?;
// Push a `ret` opcode.
write_felt(
&mut runner.vm,
&mut ptr,
Felt::from(0x208b_7fff_7fff_7ffe_u128),
)?;
// Push a pointer to the builtin cost segment.
write_maybe_relocatable(&mut runner.vm, &mut ptr, builtin_cost_segment_start)?;

let program_extra_data_length = 2;
Ok(program_extra_data_length)
}
use cairo_vm::types::relocatable::MaybeRelocatable;
use cairo_vm::vm::runners::cairo_runner::CairoRunner;
use num_traits::ToPrimitive;

#[expect(clippy::trivially_copy_pass_by_ref)]
// Reason copied: Required by `finalize_execution`
Expand Down
4 changes: 2 additions & 2 deletions crates/forge-runner/src/running/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ pub fn finalize_execution(
program_extra_data_length: usize,
tracked_resource: TrackedResource,
) -> Result<CallInfo, PostExecutionError> {
// region: Modified blockifier code
finalize_runner(runner, n_total_args, program_extra_data_length)?;
syscall_handler
.read_only_segments
.mark_as_accessed(runner)?;
// endregion

let call_result = get_call_result(runner, syscall_handler, &tracked_resource)?;

Expand All @@ -43,6 +41,7 @@ pub fn finalize_execution(
);

let syscall_handler_base = &syscall_handler.base;
// region: Modified blockifier code - added clones due to different function signature
Ok(CallInfo {
call: syscall_handler_base.call.clone().into(),
execution: CallExecution {
Expand All @@ -59,4 +58,5 @@ pub fn finalize_execution(
storage_access_tracker: syscall_handler_base.storage_access_tracker.clone(),
builtin_counters: vm_resources_without_inner_calls.prover_builtins(),
})
// endregion
}
2 changes: 1 addition & 1 deletion crates/forge-runner/src/running/setup.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::package_tests::TestDetails;
use crate::running::copied_code::prepare_program_extra_data;
use blockifier::execution::contract_class::EntryPointV1;
use blockifier::execution::entry_point::{EntryPointExecutionContext, ExecutableCallEntryPoint};
use blockifier::execution::entry_point_execution::prepare_program_extra_data;
use blockifier::execution::errors::PreExecutionError;
use blockifier::execution::execution_utils::ReadOnlySegments;
use blockifier::execution::syscalls::hint_processor::SyscallHintProcessor;
Expand Down
Loading