Skip to content

Commit 88a0573

Browse files
starknet_os_flow_tests: fuzz test call/libcall bad entrypoint scenario
1 parent 8f11790 commit 88a0573

8 files changed

Lines changed: 403 additions & 21 deletions

File tree

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.

crates/blockifier_test_utils/resources/feature_contracts/cairo0/compiled/fuzz_revert_compiled.json

Lines changed: 134 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
],
3939
"EXTERNAL": [
4040
{
41-
"offset": 578,
41+
"offset": 658,
4242
"selector": "0x8e64dfac867f301a439703710296f437e9f91d1bba17cfea5ad7f137a5acd"
4343
},
4444
{
@@ -110,18 +110,54 @@
110110
"__main__",
111111
"__main__.test_revert_fuzz"
112112
],
113-
"end_pc": 574,
113+
"end_pc": 606,
114114
"flow_tracking_data": {
115115
"ap_tracking": {
116116
"group": 24,
117-
"offset": 70
117+
"offset": 165
118+
},
119+
"reference_ids": {}
120+
},
121+
"name": "error_message",
122+
"start_pc": 602,
123+
"value": "should_fail_call_non_existing_entry_point"
124+
},
125+
{
126+
"accessible_scopes": [
127+
"__main__",
128+
"__main__",
129+
"__main__.test_revert_fuzz"
130+
],
131+
"end_pc": 646,
132+
"flow_tracking_data": {
133+
"ap_tracking": {
134+
"group": 24,
135+
"offset": 166
136+
},
137+
"reference_ids": {}
138+
},
139+
"name": "error_message",
140+
"start_pc": 642,
141+
"value": "should_fail_libcall_non_existing_entry_point"
142+
},
143+
{
144+
"accessible_scopes": [
145+
"__main__",
146+
"__main__",
147+
"__main__.test_revert_fuzz"
148+
],
149+
"end_pc": 654,
150+
"flow_tracking_data": {
151+
"ap_tracking": {
152+
"group": 24,
153+
"offset": 72
118154
},
119155
"reference_ids": {
120156
"__main__.test_revert_fuzz.scenario": 8
121157
}
122158
},
123159
"name": "error_message",
124-
"start_pc": 570,
160+
"start_pc": 650,
125161
"value": "Unknown scenario: {scenario}."
126162
}
127163
],
@@ -701,20 +737,100 @@
701737
"0x48127feb7fff8000",
702738
"0x48127feb7fff8000",
703739
"0x208b7fff7fff7ffe",
740+
"0x4826800180018000",
741+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff3",
742+
"0x20680017fff7fff",
743+
"0x26",
744+
"0x48127fed7fff8000",
745+
"0x48127fed7fff8000",
746+
"0x48127fed7fff8000",
747+
"0x480a80007fff8000",
748+
"0x1104800180018000",
749+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffe8a",
750+
"0x48127ffc7fff8000",
751+
"0x48127ffc7fff8000",
752+
"0x48127ffc7fff8000",
753+
"0x480a80007fff8000",
754+
"0x1104800180018000",
755+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffe84",
756+
"0x48127ffc7fff8000",
757+
"0x48127ffc7fff8000",
758+
"0x48127ffc7fff8000",
759+
"0x480a80007fff8000",
760+
"0x1104800180018000",
761+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffe7e",
762+
"0x1104800180018000",
763+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffdb2",
764+
"0x48127ff77fff8000",
765+
"0x48127fc57fff8000",
766+
"0x48127fde7fff8000",
767+
"0x480680017fff8000",
768+
"0x0",
769+
"0x48127ffb7fff8000",
770+
"0x1104800180018000",
771+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffdaf",
772+
"0x480680017fff8000",
773+
"0x1",
774+
"0x400680017fff7fff",
775+
"0x0",
776+
"0x48127ffc7fff8000",
777+
"0x48127feb7fff8000",
778+
"0x48127feb7fff8000",
779+
"0x208b7fff7fff7ffe",
780+
"0x4826800180018000",
781+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff2",
782+
"0x20680017fff7fff",
783+
"0x26",
784+
"0x48127fec7fff8000",
785+
"0x48127fec7fff8000",
786+
"0x48127fec7fff8000",
787+
"0x480a80007fff8000",
788+
"0x1104800180018000",
789+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffe62",
790+
"0x48127ffc7fff8000",
791+
"0x48127ffc7fff8000",
792+
"0x48127ffc7fff8000",
793+
"0x480a80007fff8000",
794+
"0x1104800180018000",
795+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffe5c",
796+
"0x48127ffc7fff8000",
797+
"0x48127ffc7fff8000",
798+
"0x48127ffc7fff8000",
799+
"0x480a80007fff8000",
800+
"0x1104800180018000",
801+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffe56",
802+
"0x1104800180018000",
803+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffd8a",
804+
"0x48127ff77fff8000",
805+
"0x48127fc57fff8000",
806+
"0x48127fde7fff8000",
807+
"0x480680017fff8000",
808+
"0x0",
809+
"0x48127ffb7fff8000",
810+
"0x1104800180018000",
811+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffd93",
812+
"0x480680017fff8000",
813+
"0x1",
814+
"0x400680017fff7fff",
815+
"0x0",
816+
"0x48127ffc7fff8000",
817+
"0x48127feb7fff8000",
818+
"0x48127feb7fff8000",
819+
"0x208b7fff7fff7ffe",
704820
"0x480680017fff8000",
705821
"0x0",
706822
"0x400680017fff7fff",
707823
"0x1",
708-
"0x48127fed7fff8000",
709-
"0x48127fed7fff8000",
710-
"0x48127fed7fff8000",
824+
"0x48127feb7fff8000",
825+
"0x48127feb7fff8000",
826+
"0x48127feb7fff8000",
711827
"0x208b7fff7fff7ffe",
712828
"0x402b7ffd7ffc7ffd",
713829
"0x480280007ffb8000",
714830
"0x480280017ffb8000",
715831
"0x480280027ffb8000",
716832
"0x1104800180018000",
717-
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffe98",
833+
"0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffe48",
718834
"0x40780017fff7fff",
719835
"0x1",
720836
"0x48127ffc7fff8000",
@@ -907,7 +1023,7 @@
9071023
}
9081024
}
9091025
],
910-
"584": [
1026+
"664": [
9111027
{
9121028
"accessible_scopes": [
9131029
"__main__",
@@ -939,6 +1055,10 @@
9391055
"type": "const",
9401056
"value": 1
9411057
},
1058+
"__main__.SCENARIO_CALL_NON_EXISTING_ENTRY_POINT": {
1059+
"type": "const",
1060+
"value": 14
1061+
},
9421062
"__main__.SCENARIO_CALL_UNDEPLOYED": {
9431063
"type": "const",
9441064
"value": 13
@@ -967,6 +1087,10 @@
9671087
"type": "const",
9681088
"value": 10
9691089
},
1090+
"__main__.SCENARIO_LIBRARY_CALL_NON_EXISTING_ENTRY_POINT": {
1091+
"type": "const",
1092+
"value": 15
1093+
},
9701094
"__main__.SCENARIO_PANIC": {
9711095
"type": "const",
9721096
"value": 6
@@ -1597,7 +1721,7 @@
15971721
"decorators": [
15981722
"external"
15991723
],
1600-
"pc": 578,
1724+
"pc": 658,
16011725
"type": "function"
16021726
},
16031727
"__wrappers__.test_revert_fuzz.Args": {

crates/blockifier_test_utils/resources/feature_contracts/cairo0/fuzz_revert.cairo

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ const SCENARIO_LIBRARY_CALL_NON_EXISTING = 10;
2727
const SCENARIO_SHA256 = 11;
2828
const SCENARIO_KECCAK = 12;
2929
const SCENARIO_CALL_UNDEPLOYED = 13;
30+
const SCENARIO_CALL_NON_EXISTING_ENTRY_POINT = 14;
31+
const SCENARIO_LIBRARY_CALL_NON_EXISTING_ENTRY_POINT = 15;
3032

3133
// selector_from_name("pop_front").
3234
const POP_FRONT_SELECTOR = 0x289c2d7d6351cd03d4f928bde75fa14d5f52e32bdbc750d5296e1b48c12f1c3;
@@ -216,6 +218,32 @@ func test_revert_fuzz{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_chec
216218
return ();
217219
}
218220

221+
if (scenario == SCENARIO_CALL_NON_EXISTING_ENTRY_POINT) {
222+
let address = pop_front(orchestrator);
223+
let selector = pop_front(orchestrator);
224+
let _should_unwrap = pop_front(orchestrator);
225+
call_contract(
226+
contract_address=address, function_selector=selector, calldata_size=0, calldata=new()
227+
);
228+
with_attr error_message("should_fail_call_non_existing_entry_point") {
229+
assert 0 = 1;
230+
}
231+
return ();
232+
}
233+
234+
if (scenario == SCENARIO_LIBRARY_CALL_NON_EXISTING_ENTRY_POINT) {
235+
let class_hash = pop_front(orchestrator);
236+
let selector = pop_front(orchestrator);
237+
let _should_unwrap = pop_front(orchestrator);
238+
library_call(
239+
class_hash=class_hash, function_selector=selector, calldata_size=0, calldata=new()
240+
);
241+
with_attr error_message("should_fail_libcall_non_existing_entry_point") {
242+
assert 0 = 1;
243+
}
244+
return ();
245+
}
246+
219247
with_attr error_message("Unknown scenario: {scenario}.") {
220248
assert 1 = 0;
221249
}

crates/blockifier_test_utils/resources/feature_contracts/cairo1/fuzz_revert.cairo

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ trait IOrchestrator<TContractState> {
44
fn get_index(ref self: TContractState) -> felt252;
55
fn set_index(ref self: TContractState, index: felt252);
66
fn should_fail_undeployed_panic_message(ref self: TContractState) -> felt252;
7+
fn should_fail_call_no_entrypoint_panic_message(ref self: TContractState) -> felt252;
8+
fn should_fail_libcall_no_entrypoint_panic_message(ref self: TContractState) -> felt252;
79
}
810

911
#[starknet::contract]
@@ -35,6 +37,8 @@ mod FuzzRevertContract {
3537
const SCENARIO_SHA256: felt252 = 11;
3638
const SCENARIO_KECCAK: felt252 = 12;
3739
const SCENARIO_CALL_UNDEPLOYED: felt252 = 13;
40+
const SCENARIO_CALL_NON_EXISTING_ENTRY_POINT: felt252 = 14;
41+
const SCENARIO_LIBRARY_CALL_NON_EXISTING_ENTRY_POINT: felt252 = 15;
3842

3943
#[storage]
4044
struct Storage {
@@ -67,6 +71,32 @@ mod FuzzRevertContract {
6771
}
6872
}
6973
}
74+
75+
/// Handle a syscall that immediately fails (e.g. calling a non-existing entry point).
76+
fn handle_syscall_immediate_failure(
77+
ref self: ContractState,
78+
result: SyscallResult<Span<felt252>>,
79+
panic_message_if_ok: felt252,
80+
should_unwrap: bool
81+
) {
82+
match result {
83+
Result::Ok(_) => panic_with_felt252(panic_message_if_ok),
84+
Result::Err(mut error) => {
85+
// Syscall failed immediately, so no inner calls could have modified the
86+
// orchestrator index. No need to handle index propagation (the !should_unwrap
87+
// case).
88+
if should_unwrap {
89+
// The inner error does not contain the orchestrator index, so to propagate
90+
// the error the index must be prepended.
91+
let mut new_error: Array<felt252> = array![self.orchestrator().get_index()];
92+
for elem in error {
93+
new_error.append(elem);
94+
}
95+
panic(new_error);
96+
}
97+
}
98+
}
99+
}
70100
}
71101

72102
/// If this contract is deployed as part of the fuzz test "deploy" scenario, the orchestrator
@@ -86,6 +116,7 @@ mod FuzzRevertContract {
86116
self.orchestrator_address.write(orchestrator_address);
87117
}
88118

119+
89120
#[external(v0)]
90121
fn test_revert_fuzz(ref self: ContractState) {
91122
let orchestrator = self.orchestrator();
@@ -191,6 +222,30 @@ mod FuzzRevertContract {
191222
panic_with_felt252(orchestrator.should_fail_undeployed_panic_message());
192223
}
193224

225+
if scenario == SCENARIO_CALL_NON_EXISTING_ENTRY_POINT {
226+
let address: ContractAddress = orchestrator.pop_front().try_into().unwrap();
227+
let selector = orchestrator.pop_front();
228+
let should_unwrap = orchestrator.pop_front();
229+
self
230+
.handle_syscall_immediate_failure(
231+
syscalls::call_contract_syscall(address, selector, array![].span()),
232+
orchestrator.should_fail_call_no_entrypoint_panic_message(),
233+
should_unwrap != 0
234+
);
235+
}
236+
237+
if scenario == SCENARIO_LIBRARY_CALL_NON_EXISTING_ENTRY_POINT {
238+
let class_hash: ClassHash = orchestrator.pop_front().try_into().unwrap();
239+
let selector = orchestrator.pop_front();
240+
let should_unwrap = orchestrator.pop_front();
241+
self
242+
.handle_syscall_immediate_failure(
243+
syscalls::library_call_syscall(class_hash, selector, array![].span()),
244+
orchestrator.should_fail_libcall_no_entrypoint_panic_message(),
245+
should_unwrap != 0
246+
);
247+
}
248+
194249
// Unless explicitly stated otherwise, the next operation should be in the current call
195250
// context.
196251
test_revert_fuzz(ref self);

0 commit comments

Comments
 (0)