Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit d25ac3f

Browse files
fguthmannfannyguthmannmatias-gonzSantiagoPittellajuanbono
authored
Test multi syscall (#687)
* create multy syscall * remove the replace syscall, it failed because the contract adress didn't match * added library call_syscall * wip * wip * wip * wip * work in progress * remove .sjon files from starknet_programs * finished implemented all the syscalls * reorder code, create one call to syscall * fix pull bug * Update tests/multi_syscall_test.rs Co-authored-by: Matías Ignacio González <maigonzalez@fi.uba.ar> * Update starknet_programs/cairo1/multi_syscall_test.cairo Co-authored-by: Matías Ignacio González <maigonzalez@fi.uba.ar> * Update starknet_programs/cairo1/contract_a.cairo Co-authored-by: Matías Ignacio González <maigonzalez@fi.uba.ar> * Update tests/multi_syscall_test.rs Co-authored-by: Matías Ignacio González <maigonzalez@fi.uba.ar> * added test syscall for deploy * make format changes * corrected make clippy error * get_caller_address and get_contract_address return a adress * failed of get_contract_address * failed of get_contract_address * wip * modify the selector entrypoint_selector to be function specific * wip * wip * wip * add input to cairo functions * coorect format problem * wip * wip * wip * remove format problem * Fix sierra class hash calculation (#886) * reproduce bug * use pythonic formatter * rename test * fix test * cargo fmt * Fail with an Err transactions whose calculated fee exceed `max_fee` (#892) * Make tx fail when actual_fee exceeds max_fee * Changed test * Formatting * Fix logic * Leave fail only without charging * Change test * Fix test broken by better fee calc * Fixed test fee * Update fee on test_deploy_account * Remove comment --------- Co-authored-by: Juan Bono <juanbono94@gmail.com> * Fix test_get_nonce_at (#910) * Fix test_get_nonce_at * Rely on another contract * fix get_sorted_events bug (#912) * fix get_sorted_events bug * fmt * fix clippy --------- Co-authored-by: Estéfano Bargas <estefano.bargas@fing.edu.uy> * Added documentations to syscalls/deprecated_syscall_handler module (#883) * added comments to file syscalls/deprecated_syscall_handler-module' * Update src/syscalls/deprecated_syscall_handler.rs Co-authored-by: Matías Ignacio González <maigonzalez@fi.uba.ar> * Update src/syscalls/deprecated_syscall_handler.rs Co-authored-by: Matías Ignacio González <maigonzalez@fi.uba.ar> --------- Co-authored-by: fannyguthmann <fanny.guthmann@post.idc.ac.il> Co-authored-by: Juan Bono <juanbono94@gmail.com> Co-authored-by: Matías Ignacio González <maigonzalez@fi.uba.ar> * wip * Modify the tests * fixed clippy errors --------- Co-authored-by: fannyguthmann <fanny.guthmann@post.idc.ac.il> Co-authored-by: Matías Ignacio González <maigonzalez@fi.uba.ar> Co-authored-by: SantiagoPittella <pittellasantiago@gmail.com> Co-authored-by: Juan Bono <juanbono94@gmail.com> Co-authored-by: Estéfano Bargas <estefano.bargas@fing.edu.uy>
1 parent 1102682 commit d25ac3f

File tree

3 files changed

+359
-1
lines changed

3 files changed

+359
-1
lines changed

starknet_programs/cairo1/contract_a.cairo

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#[contract]
22
mod ContractA {
33
use traits::Into;
4-
use starknet::info::get_contract_address;
54
struct Storage {
65
value: u128,
76
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#[contract]
2+
mod multy_syscall {
3+
use starknet::get_caller_address;
4+
use starknet::get_contract_address;
5+
use starknet::get_execution_info_syscall;
6+
use starknet::replace_class_syscall;
7+
use starknet::library_call_syscall;
8+
use starknet::call_contract_syscall;
9+
use starknet::send_message_to_l1_syscall;
10+
use starknet::storage_read_syscall;
11+
use starknet::storage_write_syscall;
12+
use starknet::deploy_syscall;
13+
14+
use starknet::storage_access::{StorageAddress, storage_address_try_from_felt252};
15+
use starknet::contract_address::ContractAddress;
16+
use array::{Array, ArrayTrait, Span, SpanTrait};
17+
use result::ResultTrait;
18+
use starknet::info::ExecutionInfo;
19+
use option::OptionTrait;
20+
use starknet::class_hash::ClassHash;
21+
use traits::TryInto;
22+
use starknet::class_hash::Felt252TryIntoClassHash;
23+
use box::Box;
24+
use traits::Into;
25+
use box::BoxTrait;
26+
27+
#[external]
28+
fn caller_address() -> ContractAddress {
29+
get_caller_address()
30+
}
31+
32+
#[external]
33+
fn contract_address() -> ContractAddress {
34+
get_contract_address()
35+
}
36+
37+
#[external]
38+
fn execution_info_syscall() -> (ContractAddress, ContractAddress) {
39+
let return_data = get_execution_info_syscall().unwrap().unbox();
40+
(return_data.caller_address, return_data.contract_address)
41+
}
42+
43+
44+
#[external]
45+
fn test_library_call_syscall(class_hash: ClassHash, function_selector: felt252, number: felt252) -> felt252 {
46+
let mut calldata = ArrayTrait::new();
47+
calldata.append(number);
48+
let return_data = library_call_syscall(class_hash, function_selector, calldata.span()).unwrap();
49+
*return_data.get(0_usize).unwrap().unbox()
50+
}
51+
52+
#[external]
53+
fn test_call_contract_syscall(function_selector: felt252, number: felt252) -> felt252 {
54+
let mut calldata = ArrayTrait::new();
55+
calldata.append(number);
56+
let return_data = call_contract_syscall(get_contract_address(), function_selector, calldata.span()).unwrap();
57+
*return_data.get(0_usize).unwrap().unbox()
58+
59+
}
60+
61+
#[external]
62+
fn test_send_message_to_l1(to_address: felt252, payload_0: felt252, payload_1: felt252) -> () {
63+
let mut calldata = ArrayTrait::new();
64+
calldata.append(payload_0);
65+
calldata.append(payload_1);
66+
let return_data = send_message_to_l1_syscall(to_address, calldata.span()).unwrap();
67+
return_data
68+
}
69+
70+
#[external]
71+
fn read()-> felt252{
72+
//write to storage
73+
let address = storage_address_try_from_felt252(3534535754756246375475423547453).unwrap();
74+
storage_write_syscall(0, address, 'Hello');
75+
76+
//read from storage
77+
match storage_read_syscall(0, address) {
78+
Result::Ok(value) => value,
79+
Result::Err(revert_reason) => *revert_reason.span().at(0),
80+
}
81+
}
82+
83+
#[event]
84+
fn EmitEvent(n: felt252){}
85+
86+
#[external]
87+
fn trigger_events() {
88+
EmitEvent(1);
89+
EmitEvent(2);
90+
EmitEvent(3);
91+
}
92+
93+
#[external]
94+
fn get_number(number: felt252) -> felt252 {
95+
number
96+
}
97+
}

tests/multi_syscall_test.rs

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
use cairo_lang_starknet::casm_contract_class::CasmContractClass;
2+
use cairo_vm::felt::Felt252;
3+
use num_traits::{Num, Zero};
4+
use starknet_in_rust::utils::calculate_sn_keccak;
5+
use starknet_in_rust::EntryPointType;
6+
use starknet_in_rust::{
7+
definitions::{block_context::BlockContext, constants::TRANSACTION_VERSION},
8+
execution::{
9+
execution_entry_point::ExecutionEntryPoint, CallInfo, CallType, OrderedEvent,
10+
OrderedL2ToL1Message, TransactionExecutionContext,
11+
},
12+
state::cached_state::CachedState,
13+
state::{in_memory_state_reader::InMemoryStateReader, ExecutionResourcesManager},
14+
utils::{Address, ClassHash},
15+
};
16+
use std::{collections::HashMap, sync::Arc, vec};
17+
18+
#[test]
19+
fn test_multiple_syscall() {
20+
// Create program and entry point types for contract class
21+
let program_data = include_bytes!("../starknet_programs/cairo1/multi_syscall_test.casm");
22+
let contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap();
23+
24+
// Create state reader with class hash data
25+
let mut contract_class_cache: HashMap<[u8; 32], _> = HashMap::new();
26+
27+
let address = Address(1111.into());
28+
let class_hash: ClassHash = [1; 32];
29+
let nonce = Felt252::zero();
30+
31+
contract_class_cache.insert(class_hash, contract_class);
32+
let mut state_reader = InMemoryStateReader::default();
33+
state_reader
34+
.address_to_class_hash_mut()
35+
.insert(address.clone(), class_hash);
36+
state_reader
37+
.address_to_nonce_mut()
38+
.insert(address.clone(), nonce);
39+
40+
// Create state from the state_reader and contract cache.
41+
let mut state = CachedState::new(
42+
Arc::new(state_reader),
43+
None,
44+
Some(contract_class_cache.clone()),
45+
);
46+
47+
// Create an execution entry point
48+
let calldata = [].to_vec();
49+
let caller_address = Address(0000.into());
50+
let entry_point_type = EntryPointType::External;
51+
52+
// Block for get_caller_address.
53+
{
54+
let call_info = test_syscall(
55+
"caller_address",
56+
address.clone(),
57+
vec![],
58+
caller_address.clone(),
59+
entry_point_type,
60+
class_hash,
61+
&mut state,
62+
);
63+
assert_eq!(call_info.retdata, vec![caller_address.clone().0])
64+
}
65+
66+
// Block for get_contact_address.
67+
{
68+
let call_info = test_syscall(
69+
"contract_address",
70+
address.clone(),
71+
vec![],
72+
caller_address.clone(),
73+
entry_point_type,
74+
class_hash,
75+
&mut state,
76+
);
77+
assert_eq!(call_info.retdata, vec![address.clone().0])
78+
}
79+
// Block for get_execution_info_syscall.
80+
{
81+
let call_info = test_syscall(
82+
"execution_info_syscall",
83+
address.clone(),
84+
calldata.clone(),
85+
caller_address.clone(),
86+
entry_point_type,
87+
class_hash,
88+
&mut state,
89+
);
90+
assert_eq!(call_info.retdata, vec![0.into(), 1111.into()]);
91+
}
92+
93+
// Block for library_call_syscall
94+
{
95+
let entrypoint_selector =
96+
Felt252::from_bytes_be(&calculate_sn_keccak("get_number".as_bytes()));
97+
let new_call_data = vec![
98+
Felt252::from_bytes_be(&class_hash),
99+
entrypoint_selector,
100+
Felt252::from(25),
101+
];
102+
let call_info = test_syscall(
103+
"test_library_call_syscall",
104+
address.clone(),
105+
new_call_data,
106+
caller_address.clone(),
107+
entry_point_type,
108+
class_hash,
109+
&mut state,
110+
);
111+
assert_eq!(call_info.retdata, vec![25.into()])
112+
}
113+
114+
// Block for call_contract_syscall
115+
{
116+
let entrypoint_selector =
117+
Felt252::from_bytes_be(&calculate_sn_keccak("get_number".as_bytes()));
118+
let new_call_data = vec![entrypoint_selector, Felt252::from(25)];
119+
let call_info = test_syscall(
120+
"test_call_contract_syscall",
121+
address.clone(),
122+
new_call_data,
123+
caller_address.clone(),
124+
entry_point_type,
125+
class_hash,
126+
&mut state,
127+
);
128+
assert_eq!(call_info.retdata, vec![25.into()])
129+
}
130+
131+
// Block for send_message_to_l1_syscall
132+
{
133+
let new_call_data = vec![2222.into(), Felt252::from(25), Felt252::from(30)];
134+
let call_info = test_syscall(
135+
"test_send_message_to_l1",
136+
address.clone(),
137+
new_call_data,
138+
caller_address.clone(),
139+
entry_point_type,
140+
class_hash,
141+
&mut state,
142+
);
143+
assert_eq!(
144+
call_info.l2_to_l1_messages,
145+
vec![OrderedL2ToL1Message {
146+
order: 0,
147+
to_address: Address(2222.into()),
148+
payload: vec![Felt252::from(25), Felt252::from(30)],
149+
},]
150+
)
151+
}
152+
153+
// Block for read write
154+
{
155+
let call_info = test_syscall(
156+
"read",
157+
address.clone(),
158+
calldata.clone(),
159+
caller_address.clone(),
160+
entry_point_type,
161+
class_hash,
162+
&mut state,
163+
);
164+
assert_eq!(
165+
call_info.retdata,
166+
vec![Felt252::from_str_radix("310939249775", 10).unwrap()]
167+
)
168+
}
169+
170+
// Block for emit
171+
{
172+
let call_info = test_syscall(
173+
"trigger_events",
174+
address,
175+
calldata,
176+
caller_address,
177+
entry_point_type,
178+
class_hash,
179+
&mut state,
180+
);
181+
assert_eq!(
182+
call_info.events,
183+
vec![
184+
OrderedEvent {
185+
order: 0,
186+
keys: vec![Felt252::from_str_radix(
187+
"1533133552972353850845856330693290141476612241335297758062928121906575244541",
188+
10
189+
)
190+
.unwrap()],
191+
data: vec![1.into()]
192+
},
193+
OrderedEvent {
194+
order: 1,
195+
keys: vec![Felt252::from_str_radix(
196+
"1533133552972353850845856330693290141476612241335297758062928121906575244541",
197+
10
198+
)
199+
.unwrap()],
200+
data: vec![2.into()]
201+
},
202+
OrderedEvent {
203+
order: 2,
204+
keys: vec![Felt252::from_str_radix(
205+
"1533133552972353850845856330693290141476612241335297758062928121906575244541",
206+
10
207+
)
208+
.unwrap()],
209+
data: vec![3.into()]
210+
}
211+
]
212+
)
213+
}
214+
}
215+
216+
fn test_syscall(
217+
entrypoint_selector: &str,
218+
address: Address,
219+
calldata: Vec<Felt252>,
220+
caller_address: Address,
221+
entry_point_type: EntryPointType,
222+
class_hash: [u8; 32],
223+
state: &mut CachedState<InMemoryStateReader>,
224+
) -> CallInfo {
225+
let entrypoint_selector =
226+
Felt252::from_bytes_be(&calculate_sn_keccak(entrypoint_selector.as_bytes()));
227+
let exec_entry_point = ExecutionEntryPoint::new(
228+
address,
229+
calldata,
230+
Felt252::new(entrypoint_selector),
231+
caller_address,
232+
entry_point_type,
233+
Some(CallType::Delegate),
234+
Some(class_hash),
235+
100000,
236+
);
237+
238+
// Execute the entrypoint
239+
let block_context = BlockContext::default();
240+
let mut tx_execution_context = TransactionExecutionContext::new(
241+
Address(0.into()),
242+
Felt252::zero(),
243+
Vec::new(),
244+
0,
245+
10.into(),
246+
block_context.invoke_tx_max_n_steps(),
247+
TRANSACTION_VERSION.clone(),
248+
);
249+
let mut resources_manager = ExecutionResourcesManager::default();
250+
exec_entry_point
251+
.execute(
252+
state,
253+
&block_context,
254+
&mut resources_manager,
255+
&mut tx_execution_context,
256+
false,
257+
block_context.invoke_tx_max_n_steps(),
258+
)
259+
.unwrap()
260+
.call_info
261+
.unwrap()
262+
}

0 commit comments

Comments
 (0)