Skip to content

Commit 161eb25

Browse files
authored
Remove deploy_at as cheatcode (#3676)
Towards #3659 commit-id:b3b58bf4 --- **Stack**: - #3700 - #3699 - #3695 - #3676⚠️ *Part of a stack created by [spr](https://github.com/ejoffe/spr). Do not merge manually using the UI - doing so may have unexpected results.*
1 parent 798c2b3 commit 161eb25

File tree

9 files changed

+50
-160
lines changed

9 files changed

+50
-160
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3030

3131
### Changed
3232

33-
- `deploy` method on `ContractClass` instance now fails immediately upon encountering an error, preventing the error from being caught. This change aligns with the behavior of the `deploy_syscall` on the network
33+
- `deploy` and `deploy_at` methods on `ContractClass` instance now fail immediately upon encountering an error, preventing the error from being caught. This change aligns with the behavior of the `deploy_syscall` on the network
3434

3535
### Cast
3636

crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/cheated_syscalls.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,17 @@ pub fn deploy_syscall(
9494
deployer_address
9595
};
9696

97-
let deployed_contract_address = calculate_contract_address(
98-
request.contract_address_salt,
99-
request.class_hash,
100-
&request.constructor_calldata,
101-
deployer_address_for_calculation,
102-
)?;
97+
let deployed_contract_address =
98+
if let Some(contract_address) = cheatnet_state.next_address_for_deployment() {
99+
contract_address
100+
} else {
101+
calculate_contract_address(
102+
request.contract_address_salt,
103+
request.class_hash,
104+
&request.constructor_calldata,
105+
deployer_address_for_calculation,
106+
)?
107+
};
103108

104109
let ctor_context = ConstructorContext {
105110
class_hash: request.class_hash,

crates/cheatnet/src/runtime_extensions/forge_runtime_extension/mod.rs

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use crate::runtime_extensions::{
1111
forge_runtime_extension::cheatcodes::{
1212
CheatcodeError,
1313
declare::declare,
14-
deploy::deploy_at,
1514
generate_random_felt::generate_random_felt,
1615
get_class_hash::get_class_hash,
1716
l1_handler_execute::l1_handler_execute,
@@ -26,7 +25,6 @@ use blockifier::context::TransactionContext;
2625
use blockifier::execution::call_info::{CallExecution, CallInfo};
2726
use blockifier::execution::contract_class::TrackedResource;
2827
use blockifier::execution::entry_point::CallEntryPoint;
29-
use blockifier::execution::syscalls::syscall_executor::SyscallExecutor;
3028
use blockifier::execution::syscalls::vm_syscall_utils::{SyscallSelector, SyscallUsageMap};
3129
use blockifier::state::errors::StateError;
3230
use cairo_vm::vm::runners::cairo_runner::CairoRunner;
@@ -191,25 +189,14 @@ impl<'a> ExtensionLogic for ForgeExtension<'a> {
191189

192190
handle_declare_deploy_result(declare(*state, &contract_name, self.contracts_data))
193191
}
194-
"deploy_at" => {
195-
let class_hash = input_reader.read()?;
196-
let calldata: Vec<_> = input_reader.read()?;
192+
// Internal cheatcode used to pass a contract address when calling `deploy_at`.
193+
"set_deploy_at_address" => {
197194
let contract_address = input_reader.read()?;
198-
let cheatnet_runtime = &mut extended_runtime.extended_runtime;
199-
let syscall_handler = &mut cheatnet_runtime.extended_runtime.hint_handler;
200195

201-
syscall_handler.increment_syscall_count_by(&SyscallSelector::Deploy, 1);
202-
syscall_handler
203-
.base
204-
.increment_syscall_linear_factor_by(&SyscallSelector::Deploy, calldata.len());
196+
let state = &mut *extended_runtime.extended_runtime.extension.cheatnet_state;
197+
state.set_next_deploy_at_address(contract_address);
205198

206-
handle_declare_deploy_result(deploy_at(
207-
syscall_handler,
208-
cheatnet_runtime.extension.cheatnet_state,
209-
&class_hash,
210-
&calldata,
211-
contract_address,
212-
))
199+
Ok(CheatcodeHandlingResult::from_serializable(()))
213200
}
214201
"precalculate_address" => {
215202
let class_hash = input_reader.read()?;
@@ -223,7 +210,7 @@ impl<'a> ExtensionLogic for ForgeExtension<'a> {
223210

224211
Ok(CheatcodeHandlingResult::from_serializable(contract_address))
225212
}
226-
// Internal cheat code to guarantee unique salts for each deployment
213+
// Internal cheatcode to guarantee unique salts for each deployment
227214
// when deploying via a method of the `ContractClass` struct.
228215
"get_salt" => {
229216
let state = &mut *extended_runtime.extended_runtime.extension.cheatnet_state;

crates/cheatnet/src/state.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ pub struct CheatnetState {
383383
pub detected_events: Vec<Event>,
384384
pub detected_messages_to_l1: Vec<MessageToL1>,
385385
pub deploy_salt_base: u32,
386+
pub next_deploy_at_address: Option<ContractAddress>,
386387
pub block_info: BlockInfo,
387388
pub trace_data: TraceData,
388389
pub encountered_errors: EncounteredErrors,
@@ -410,6 +411,7 @@ impl Default for CheatnetState {
410411
detected_events: vec![],
411412
detected_messages_to_l1: vec![],
412413
deploy_salt_base: 0,
414+
next_deploy_at_address: None,
413415
block_info: SerializableBlockInfo::default().into(),
414416
trace_data: TraceData {
415417
current_call_stack: NotEmptyCallStack::from(test_call),
@@ -477,6 +479,14 @@ impl CheatnetState {
477479
self.deploy_salt_base += 1;
478480
}
479481

482+
pub fn set_next_deploy_at_address(&mut self, address: ContractAddress) {
483+
self.next_deploy_at_address = Some(address);
484+
}
485+
486+
pub fn next_address_for_deployment(&mut self) -> Option<ContractAddress> {
487+
self.next_deploy_at_address.take()
488+
}
489+
480490
#[must_use]
481491
pub fn get_salt(&self) -> ContractAddressSalt {
482492
ContractAddressSalt(Felt::from(self.deploy_salt_base))

crates/cheatnet/tests/cheatcodes/deploy.rs

Lines changed: 1 addition & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,16 @@
11
use crate::common::assertions::{ClassHashAssert, assert_success};
22
use crate::common::state::create_cached_state;
33
use crate::common::{call_contract, deploy_at_wrapper, deploy_contract, get_contracts};
4-
use cairo_vm::vm::errors::hint_errors::HintError;
54
use cheatnet::runtime_extensions::call_to_blockifier_runtime_extension::rpc::{
65
CallFailure, CallResult,
76
};
8-
use cheatnet::runtime_extensions::forge_runtime_extension::cheatcodes::CheatcodeError;
97
use cheatnet::runtime_extensions::forge_runtime_extension::cheatcodes::declare::declare;
108
use cheatnet::runtime_extensions::forge_runtime_extension::cheatcodes::storage::selector_from_name;
119
use cheatnet::state::CheatnetState;
1210
use conversions::IntoConv;
13-
use runtime::EnhancedHintError;
1411
use starknet_api::core::ContractAddress;
1512
use starknet_types_core::felt::Felt;
1613

17-
#[test]
18-
fn deploy_at_predefined_address() {
19-
let mut cached_state = create_cached_state();
20-
let mut cheatnet_state = CheatnetState::default();
21-
22-
let contracts_data = get_contracts();
23-
24-
let class_hash = declare(&mut cached_state, "HelloStarknet", &contracts_data)
25-
.unwrap()
26-
.unwrap_success();
27-
let contract_address = deploy_at_wrapper(
28-
&mut cached_state,
29-
&mut cheatnet_state,
30-
&class_hash,
31-
&[],
32-
ContractAddress::from(1_u8),
33-
)
34-
.unwrap();
35-
36-
assert_eq!(contract_address, ContractAddress::from(1_u8));
37-
38-
let selector = selector_from_name("get_balance");
39-
let output = call_contract(
40-
&mut cached_state,
41-
&mut cheatnet_state,
42-
&contract_address,
43-
selector,
44-
&[],
45-
);
46-
47-
assert_success(output, &[Felt::from(0)]);
48-
}
49-
50-
#[test]
51-
fn deploy_two_at_the_same_address() {
52-
let mut cached_state = create_cached_state();
53-
let mut cheatnet_state = CheatnetState::default();
54-
55-
let contracts_data = get_contracts();
56-
57-
let class_hash = declare(&mut cached_state, "HelloStarknet", &contracts_data)
58-
.unwrap()
59-
.unwrap_success();
60-
deploy_at_wrapper(
61-
&mut cached_state,
62-
&mut cheatnet_state,
63-
&class_hash,
64-
&[],
65-
ContractAddress::from(1_u8),
66-
)
67-
.unwrap();
68-
69-
let result = deploy_at_wrapper(
70-
&mut cached_state,
71-
&mut cheatnet_state,
72-
&class_hash,
73-
&[],
74-
ContractAddress::from(1_u8),
75-
);
76-
77-
assert!(matches!(
78-
result,
79-
Err(CheatcodeError::Unrecoverable(EnhancedHintError::Hint(HintError::CustomHint(err))))
80-
if err.as_ref() == "Address is already taken"
81-
));
82-
}
83-
8414
#[test]
8515
fn call_predefined_contract_from_proxy_contract() {
8616
let mut cached_state = create_cached_state();
@@ -95,6 +25,7 @@ fn call_predefined_contract_from_proxy_contract() {
9525
)
9626
.unwrap()
9727
.unwrap_success();
28+
9829
let cheat_caller_address_checker_address = deploy_at_wrapper(
9930
&mut cached_state,
10031
&mut cheatnet_state,
@@ -182,31 +113,6 @@ fn deploy_contract_on_predefined_address_after_its_usage() {
182113
assert_success(output, &[]);
183114
}
184115

185-
#[test]
186-
fn try_to_deploy_at_0() {
187-
let mut cached_state = create_cached_state();
188-
let mut cheatnet_state = CheatnetState::default();
189-
190-
let contracts_data = get_contracts();
191-
192-
let class_hash = declare(&mut cached_state, "HelloStarknet", &contracts_data)
193-
.unwrap()
194-
.unwrap_success();
195-
let output = deploy_at_wrapper(
196-
&mut cached_state,
197-
&mut cheatnet_state,
198-
&class_hash,
199-
&[],
200-
ContractAddress::from(0_u8),
201-
);
202-
203-
assert!(match output {
204-
Err(CheatcodeError::Unrecoverable(EnhancedHintError::Hint(HintError::CustomHint(msg)))) =>
205-
msg.as_ref() == "Cannot deploy contract at address 0.",
206-
_ => false,
207-
});
208-
}
209-
210116
#[test]
211117
fn deploy_invokes_constructor() {
212118
let mut cached_state = create_cached_state();

crates/forge/tests/data/contracts/panicking_constructor.cairo

Lines changed: 0 additions & 15 deletions
This file was deleted.

crates/forge/tests/integration/deploy_at.rs

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,42 +111,37 @@ fn deploy_two_at_the_same_address() {
111111
assert_case_output_contains(
112112
&result,
113113
"deploy_two_at_the_same_address",
114-
"Address is already taken",
114+
"Deployment failed: contract already deployed at address 0x000000000000000000000000000000000000000000000000000000000000007b",
115115
);
116116
}
117117

118118
#[test]
119-
fn deploy_at_error_handling() {
119+
fn fail_to_deploy_at_0() {
120120
let test = test_case!(
121121
indoc!(
122122
r#"
123-
use array::ArrayTrait;
124123
use snforge_std::{ declare, ContractClassTrait, DeclareResultTrait };
125-
use starknet::ContractAddress;
126124
127125
#[test]
128-
fn deploy_at_error_handling() {
129-
let contract_address = 123;
130-
131-
let contract = declare("PanickingConstructor").unwrap().contract_class();
132-
match contract.deploy_at(@array![], contract_address.try_into().unwrap()) {
133-
Result::Ok(_) => panic_with_felt252('shouldve panicked'),
134-
Result::Err(panic_data) => {
135-
assert(*panic_data.at(0) == 'PANIK', 'wrong 1st panic datum');
136-
assert(*panic_data.at(1) == 'DEJTA', 'wrong 2nd panic datum');
137-
},
138-
}
126+
fn deploy_at_0() {
127+
let contract = declare("HelloStarknet").unwrap().contract_class();
128+
contract.deploy_at(@array![], 0.try_into().unwrap()).unwrap();
139129
}
140130
"#
141131
),
142132
Contract::from_code_path(
143-
"PanickingConstructor".to_string(),
144-
Path::new("tests/data/contracts/panicking_constructor.cairo"),
133+
"HelloStarknet".to_string(),
134+
Path::new("tests/data/contracts/hello_starknet.cairo"),
145135
)
146136
.unwrap()
147137
);
148138

149139
let result = run_test_case(&test, ForgeTrackedResource::CairoSteps);
150140

151-
assert_passed(&result);
141+
assert_failed(&result);
142+
assert_case_output_contains(
143+
&result,
144+
"deploy_at_0",
145+
"Cannot deploy contract at address 0",
146+
);
152147
}

snforge_std/src/cheatcodes/contract_class.cairo

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,11 @@ impl ContractClassImpl of ContractClassTrait {
7878
constructor_calldata: @Array::<felt252>,
7979
contract_address: ContractAddress,
8080
) -> SyscallResult<(ContractAddress, Span<felt252>)> {
81-
let mut inputs = _prepare_calldata(self.class_hash, constructor_calldata);
82-
inputs.append(contract_address.into());
81+
execute_cheatcode_and_deserialize::<
82+
'set_deploy_at_address', (),
83+
>(array![contract_address.into()].span());
8384

84-
execute_cheatcode_and_deserialize::<'deploy_at'>(inputs.span())
85+
self.deploy(constructor_calldata)
8586
}
8687

8788
fn new<T, +Into<T, ClassHash>>(class_hash: T) -> ContractClass {

snforge_std_deprecated/src/cheatcodes/contract_class.cairo

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,11 @@ impl ContractClassImpl of ContractClassTrait {
7878
constructor_calldata: @Array::<felt252>,
7979
contract_address: ContractAddress,
8080
) -> SyscallResult<(ContractAddress, Span<felt252>)> {
81-
let mut inputs = _prepare_calldata(self.class_hash, constructor_calldata);
82-
inputs.append(contract_address.into());
81+
execute_cheatcode_and_deserialize::<
82+
'set_deploy_at_address', (),
83+
>(array![contract_address.into()].span());
8384

84-
execute_cheatcode_and_deserialize::<'deploy_at'>(inputs.span())
85+
self.deploy(constructor_calldata)
8586
}
8687

8788
fn new<T, +Into<T, ClassHash>>(class_hash: T) -> ContractClass {

0 commit comments

Comments
 (0)