Skip to content

Commit d9b20fb

Browse files
starknet_os: parse os state diff for testing
1 parent 6aec9d9 commit d9b20fb

File tree

3 files changed

+54
-18
lines changed

3 files changed

+54
-18
lines changed

crates/starknet_os/src/io/os_output.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ fn parse_storage_changes<It: Iterator<Item = Felt> + ?Sized>(
151151
}
152152

153153
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize, serde::Serialize))]
154-
#[derive(Debug)]
154+
#[derive(Debug, PartialEq)]
155155
/// Represents the changes in a contract instance.
156156
pub struct ContractChanges {
157157
// The address of the contract.
@@ -228,7 +228,7 @@ impl ContractChanges {
228228
}
229229

230230
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize, serde::Serialize))]
231-
#[derive(Debug)]
231+
#[derive(Debug, PartialEq)]
232232
pub struct OsStateDiff {
233233
// Contracts that were changed.
234234
pub contracts: Vec<ContractChanges>,

crates/starknet_os/src/test_utils/cairo_runner.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ pub enum ValueArg {
4242

4343
/// An arg passed as a pointer. i.e., a pointer to a felt, tuple, named tuple or struct, or a
4444
/// pointer to a pointer.
45+
// TODO(Nimrod): Extend this to be able to return an entire segment without knowing the length in
46+
// advance.
4547
#[derive(Clone, Debug, Eq, PartialEq)]
4648
pub enum PointerArg {
4749
Array(Vec<MaybeRelocatable>),

crates/starknet_os/src/tests/aliases.rs

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use starknet_api::core::L2_ADDRESS_UPPER_BOUND;
1414
use starknet_api::state::StorageKey;
1515
use starknet_types_core::felt::Felt;
1616

17+
use crate::io::os_output::OsStateDiff;
1718
use crate::test_utils::cairo_runner::{
1819
initialize_and_run_cairo_0_entry_point,
1920
initialize_cairo_runner,
@@ -338,7 +339,8 @@ fn allocate_aliases_for_keys_and_replace(
338339
HashMap::new(),
339340
HashMap::new(),
340341
HashMap::new(),
341-
HashMap::from([(0, 136), (128, 128), (129, 129), (200, 132), (225, 130), (300, 133), (1111, 134), (7659, 131), (99999, 135)])
342+
HashMap::from([(0, 136), (128, 128), (129, 129), (200, 132), (225, 130), (300, 133), (1111, 134), (7659, 131), (99999, 135)]),
343+
97,
342344
)]
343345
#[case::non_allocation_of_address_lt_16_from_non_empty_storage(
344346
HashMap::from([
@@ -348,7 +350,7 @@ fn allocate_aliases_for_keys_and_replace(
348350
),
349351
(
350352
44,
351-
HashMap::from([(11, 1), (129, 1), (225, 1), (7659, 1)])
353+
HashMap::from([(11, 1), (129, 1), (225, 1), (400, 1), (7659, 1)])
352354
),
353355
(
354356
400,
@@ -358,8 +360,8 @@ fn allocate_aliases_for_keys_and_replace(
358360
HashMap::new(),
359361
HashMap::new(),
360362
HashMap::from([(0, 135), (129, 128), (225, 129), (7659, 130), (200, 131), (300, 132), (1111, 133), (99999, 134)]),
361-
HashMap::from([(0, 138), (129, 128), (225, 129), (400, 135), (700, 136), (701, 137), (1111, 133), (7659, 130)]
362-
)
363+
HashMap::from([(0, 138), (129, 128), (225, 129), (400, 135), (700, 136), (701, 137), (1111, 133), (7659, 130)]),
364+
76,
363365
)]
364366
#[case::non_allocation_with_only_trivial_updates(
365367
HashMap::from([
@@ -383,8 +385,8 @@ fn allocate_aliases_for_keys_and_replace(
383385
HashMap::new(),
384386
HashMap::new(),
385387
HashMap::new(),
386-
HashMap::from([(0, 134), (129, 128), (400, 129), (700, 131), (701, 132), (1111, 133), (7659, 130)]
387-
)
388+
HashMap::from([(0, 134), (129, 128), (400, 129), (700, 131), (701, 132), (1111, 133), (7659, 130)]),
389+
73,
388390
)]
389391
#[case::allocation_with_only_nonce_change(
390392
HashMap::new(),
@@ -398,17 +400,17 @@ fn allocate_aliases_for_keys_and_replace(
398400
]),
399401
HashMap::from([(11111, 1)]),
400402
HashMap::new(),
401-
HashMap::from([(0, 131), (11111, 128), (222222, 129), (3333333, 130)]
402-
)
403+
HashMap::from([(0, 131), (11111, 128), (222222, 129), (3333333, 130)]),
404+
49,
403405
)]
404406
#[case::non_allocation_with_trivial_class_hash_update(
405407
HashMap::new(),
406408
HashMap::from([(24, 1), (5000, 1), (6666, 1), (9999, 1), (11111, DEFAULT_CLASS_HASH),
407409
]),
408410
HashMap::new(),
409411
HashMap::from([(0, 133), (5000, 128), (11111, 129), (222222, 130), (3333333, 131), (87777, 132)]),
410-
HashMap::from([(0, 135), (5000, 128), (6666, 133), (9999, 134)]
411-
)
412+
HashMap::from([(0, 135), (5000, 128), (6666, 133), (9999, 134)]),
413+
40,
412414
)]
413415
#[case::allocation_with_partially_trivial_updates(
414416
HashMap::from([
@@ -440,14 +442,16 @@ fn allocate_aliases_for_keys_and_replace(
440442
HashMap::from([(200, 1), (500, 1), (700, 1), (800, DEFAULT_CLASS_HASH)]),
441443
HashMap::from([(700, 1), (10000, 0)]),
442444
HashMap::new(),
443-
HashMap::from([(0, 137), (200, 128), (500, 130), (600, 133), (700, 134), (701, 135), (777, 129), (800, 136), (2000, 131), (3000, 132)])
445+
HashMap::from([(0, 137), (200, 128), (500, 130), (600, 133), (700, 134), (701, 135), (777, 129), (800, 136), (2000, 131), (3000, 132)]),
446+
118
444447
)]
445448
fn test_allocate_addresses_for_state_diff_and_replace(
446449
#[case] storage_updates: HashMap<u128, HashMap<u128, u128>>,
447450
#[case] address_to_class_hash: HashMap<u128, u128>,
448451
#[case] address_to_nonce: HashMap<u128, u128>,
449452
#[case] initial_alias_storage: HashMap<u128, u128>,
450453
#[case] expected_alias_storage: HashMap<u128, u128>,
454+
#[case] contract_state_diff_len: usize,
451455
) {
452456
let runner_config = get_entrypoint_runner_config();
453457
let entrypoint = "__main__.allocate_aliases_and_replace";
@@ -516,8 +520,14 @@ fn test_allocate_addresses_for_state_diff_and_replace(
516520
MaybeRelocatable::Int(Felt::ZERO);
517521
expected_aliases_storage_flat_length
518522
])),
519-
EndpointArg::Pointer(PointerArg::Array(vec![])),
520-
EndpointArg::Pointer(PointerArg::Array(vec![])),
523+
EndpointArg::Pointer(PointerArg::Array(vec![
524+
MaybeRelocatable::Int(Felt::ZERO);
525+
contract_state_diff_len
526+
])),
527+
EndpointArg::Pointer(PointerArg::Array(vec![
528+
MaybeRelocatable::Int(Felt::ZERO);
529+
contract_state_diff_len
530+
])),
521531
];
522532

523533
let (_, explicit_return_values) = run_cairo_0_entrypoint(
@@ -532,22 +542,46 @@ fn test_allocate_addresses_for_state_diff_and_replace(
532542
)
533543
.unwrap();
534544

535-
// TODO(Nimrod): Complete this test to also compare the other return values.
536545
let [
537546
EndpointArg::Pointer(PointerArg::Array(aliases_storage_updates)),
538-
EndpointArg::Pointer(PointerArg::Array(_)),
539-
EndpointArg::Pointer(PointerArg::Array(_)),
547+
EndpointArg::Pointer(PointerArg::Array(contract_state_diff)),
548+
EndpointArg::Pointer(PointerArg::Array(contract_state_diff_with_aliases)),
540549
] = explicit_return_values.as_slice()
541550
else {
542551
panic!(
543552
"The return value doesn't match the given format.\n Got: {explicit_return_values:?}"
544553
);
545554
};
546555

556+
// Compare the aliases storage updates.
547557
let aliases_storage_updates_as_felts: Vec<Felt> =
548558
aliases_storage_updates.iter().map(|f| f.get_int().unwrap()).collect();
549559
let actual_alias_storage = parse_squashed_cairo_dict(&aliases_storage_updates_as_felts);
550560
let expected_alias_storage: HashMap<Felt, Felt> =
551561
expected_alias_storage.into_iter().map(|(key, value)| (key.into(), value.into())).collect();
552562
assert_eq!(actual_alias_storage, expected_alias_storage);
563+
564+
// Parse the OS output.
565+
let contract_state_diff_as_felts: Vec<Felt> = contract_state_diff
566+
.iter()
567+
.map(|f| f.get_int().unwrap())
568+
.chain([Felt::ZERO]) // Number of declared classes, zero in this case.
569+
.collect();
570+
let contract_state_diff_with_aliases_as_felts: Vec<Felt> = contract_state_diff_with_aliases
571+
.iter()
572+
.map(|f| f.get_int().unwrap())
573+
.chain([Felt::ZERO]) // Number of declared classes, zero in this case.
574+
.collect();
575+
let full_output = true;
576+
let os_state_diff =
577+
OsStateDiff::from_iter(&mut contract_state_diff_as_felts.into_iter(), full_output).unwrap();
578+
let os_state_diff_with_aliases = OsStateDiff::from_iter(
579+
&mut contract_state_diff_with_aliases_as_felts.into_iter(),
580+
full_output,
581+
)
582+
.unwrap();
583+
584+
// Sanity check - make sure the alias allocation is not trivial.
585+
assert!(os_state_diff != os_state_diff_with_aliases);
586+
// TODO(Nimrod): Complete this test by verifying the decompression.
553587
}

0 commit comments

Comments
 (0)