Skip to content

Commit c57addf

Browse files
authored
Cheat cairo0 contracts (#835)
<!-- Reference any GitHub issues resolved by this PR --> Closes #797 ## Introduced changes ## Breaking changes <!-- List of all breaking changes, if applicable --> ## Checklist <!-- Make sure all of these are complete --> - [x] Linked relevant issue - [ ] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [ ] Added changes to `CHANGELOG.md`
1 parent ed4e88f commit c57addf

File tree

16 files changed

+827
-6
lines changed

16 files changed

+827
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- `--clean-cache` flag
1717
- Changed interface of `L1Handler.execute` and `L1Handler` (dropped `fee` parameter, added result handling with `RevertedTransaction`)
1818
- cheatcodes (`prank`, `roll`, `warp`, `spoof`, `spy_events`) now work in a test state
19+
- cheatcodes (`prank`, `roll`, `warp`) now work on forked Cairo 0 contracts
1920

2021
#### Changed
2122

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,4 @@ rand = "0.8.5"
6767
project-root = "0.2.2"
6868
which = "4.4.0"
6969
conversions = { path = "./crates/conversions" }
70+
test-case = "3.1.0"

crates/cast/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ snapbox = "0.4.13"
2929
indoc.workspace = true
3030
reqwest = "0.11.18"
3131
tempfile = "3.8.0"
32-
test-case = "3.1.0"
32+
test-case.workspace = true
3333
fs_extra = "1.3.0"
3434
sealed_test = "1.0.0"
3535
dotenv = "0.15.0"

crates/cheatnet/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ indoc.workspace = true
3939
dotenv.workspace = true
4040
rayon.workspace = true
4141
glob = "0.3.1"
42+
test-case.workspace = true
4243

4344

4445
[lib]
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
use crate::execution::deprecated::syscalls::CheatableSyscallHandler;
2+
use crate::state::CheatnetState;
3+
use blockifier::execution::call_info::CallInfo;
4+
use blockifier::execution::contract_class::ContractClassV0;
5+
use blockifier::execution::deprecated_execution::{
6+
finalize_execution, initialize_execution_context, prepare_call_arguments, VmExecutionContext,
7+
};
8+
use blockifier::execution::entry_point::{
9+
CallEntryPoint, EntryPointExecutionContext, EntryPointExecutionResult, ExecutionResources,
10+
};
11+
use blockifier::execution::errors::VirtualMachineExecutionError;
12+
use blockifier::execution::execution_utils::Args;
13+
use blockifier::state::state_api::State;
14+
use cairo_vm::hint_processor::hint_processor_definition::HintProcessor;
15+
use cairo_vm::vm::runners::cairo_runner::{CairoArg, CairoRunner};
16+
use cairo_vm::vm::vm_core::VirtualMachine;
17+
18+
// blockifier/src/execution/deprecated_execution.rs:36 (execute_entry_point_call)
19+
pub fn execute_entry_point_call_cairo0(
20+
call: CallEntryPoint,
21+
contract_class: ContractClassV0,
22+
state: &mut dyn State,
23+
cheatnet_state: &mut CheatnetState, // Added parameter
24+
resources: &mut ExecutionResources,
25+
context: &mut EntryPointExecutionContext,
26+
) -> EntryPointExecutionResult<CallInfo> {
27+
let VmExecutionContext {
28+
mut runner,
29+
mut vm,
30+
mut syscall_handler,
31+
initial_syscall_ptr,
32+
entry_point_pc,
33+
} = initialize_execution_context(&call, contract_class, state, resources, context)?;
34+
35+
let (implicit_args, args) = prepare_call_arguments(
36+
&call,
37+
&mut vm,
38+
initial_syscall_ptr,
39+
&mut syscall_handler.read_only_segments,
40+
)?;
41+
let n_total_args = args.len();
42+
43+
// Fix the VM resources, in order to calculate the usage of this run at the end.
44+
let previous_vm_resources = syscall_handler.resources.vm_resources.clone();
45+
46+
// region: Modified blockifier code
47+
let mut cheatable_syscall_handler = CheatableSyscallHandler {
48+
syscall_handler,
49+
cheatnet_state,
50+
};
51+
52+
// Execute.
53+
cheatable_run_entry_point(
54+
&mut vm,
55+
&mut runner,
56+
&mut cheatable_syscall_handler,
57+
entry_point_pc,
58+
&args,
59+
)?;
60+
// endregion
61+
62+
Ok(finalize_execution(
63+
vm,
64+
runner,
65+
cheatable_syscall_handler.syscall_handler,
66+
call,
67+
previous_vm_resources,
68+
implicit_args,
69+
n_total_args,
70+
)?)
71+
}
72+
73+
// blockifier/src/execution/deprecated_execution.rs:192 (run_entry_point)
74+
pub fn cheatable_run_entry_point(
75+
vm: &mut VirtualMachine,
76+
runner: &mut CairoRunner,
77+
hint_processor: &mut dyn HintProcessor,
78+
entry_point_pc: usize,
79+
args: &Args,
80+
) -> Result<(), VirtualMachineExecutionError> {
81+
// region: Modified blockifier code
82+
// Opposite to blockifier
83+
let verify_secure = false;
84+
// endregion
85+
let program_segment_size = None; // Infer size from program.
86+
let args: Vec<&CairoArg> = args.iter().collect();
87+
88+
runner.run_from_entrypoint(
89+
entry_point_pc,
90+
&args,
91+
verify_secure,
92+
program_segment_size,
93+
vm,
94+
hint_processor,
95+
)?;
96+
97+
Ok(())
98+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use crate::execution::deprecated::syscalls::CheatableSyscallHandler;
2+
use crate::execution::entry_point::execute_call_entry_point;
3+
use blockifier::abi::constants;
4+
use blockifier::execution::deprecated_syscalls::DeprecatedSyscallResult;
5+
use blockifier::execution::entry_point::{CallEntryPoint, CallType};
6+
use blockifier::execution::execution_utils::ReadOnlySegment;
7+
use cairo_vm::types::relocatable::MaybeRelocatable;
8+
use cairo_vm::vm::vm_core::VirtualMachine;
9+
use conversions::StarknetConversions;
10+
use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector};
11+
use starknet_api::deprecated_contract_class::EntryPointType;
12+
use starknet_api::transaction::Calldata;
13+
14+
// blockifier/src/execution/deprecated_syscalls/hint_processor.rs:393 (execute_inner_call)
15+
pub fn execute_inner_call(
16+
call: &mut CallEntryPoint,
17+
vm: &mut VirtualMachine,
18+
syscall_handler: &mut CheatableSyscallHandler<'_>,
19+
) -> DeprecatedSyscallResult<ReadOnlySegment> {
20+
// region: Modified blockifier code
21+
let call_info = execute_call_entry_point(
22+
call,
23+
syscall_handler.syscall_handler.state,
24+
syscall_handler.cheatnet_state,
25+
syscall_handler.syscall_handler.resources,
26+
syscall_handler.syscall_handler.context,
27+
)?;
28+
// endregion
29+
30+
let retdata = &call_info.execution.retdata.0;
31+
let retdata: Vec<MaybeRelocatable> = retdata
32+
.iter()
33+
.map(|&x| MaybeRelocatable::from(x.to_felt252()))
34+
.collect();
35+
let retdata_segment_start_ptr = syscall_handler
36+
.syscall_handler
37+
.read_only_segments
38+
.allocate(vm, &retdata)?;
39+
40+
syscall_handler.syscall_handler.inner_calls.push(call_info);
41+
Ok(ReadOnlySegment {
42+
start_ptr: retdata_segment_start_ptr,
43+
length: retdata.len(),
44+
})
45+
}
46+
47+
// blockifier/src/execution/deprecated_syscalls/hint_processor.rs:409 (execute_library_call)
48+
pub fn execute_library_call(
49+
syscall_handler: &mut CheatableSyscallHandler<'_>,
50+
vm: &mut VirtualMachine,
51+
class_hash: ClassHash,
52+
code_address: Option<ContractAddress>,
53+
call_to_external: bool,
54+
entry_point_selector: EntryPointSelector,
55+
calldata: Calldata,
56+
) -> DeprecatedSyscallResult<ReadOnlySegment> {
57+
let entry_point_type = if call_to_external {
58+
EntryPointType::External
59+
} else {
60+
EntryPointType::L1Handler
61+
};
62+
let mut entry_point = CallEntryPoint {
63+
class_hash: Some(class_hash),
64+
code_address,
65+
entry_point_type,
66+
entry_point_selector,
67+
calldata,
68+
// The call context remains the same in a library call.
69+
storage_address: syscall_handler.syscall_handler.storage_address,
70+
caller_address: syscall_handler.syscall_handler.caller_address,
71+
call_type: CallType::Delegate,
72+
initial_gas: constants::INITIAL_GAS_COST,
73+
};
74+
75+
execute_inner_call(&mut entry_point, vm, syscall_handler)
76+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod cairo0_execution;
2+
pub mod calls;
3+
pub mod syscalls;

0 commit comments

Comments
 (0)