Skip to content

Commit b603c95

Browse files
starknet_os: add decompression to test_cairo_compress (#9918)
1 parent ca1ea0f commit b603c95

File tree

1 file changed

+72
-2
lines changed
  • crates/starknet_os/src/hints/hint_implementation/stateless_compression

1 file changed

+72
-2
lines changed

crates/starknet_os/src/hints/hint_implementation/stateless_compression/tests.rs

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ use crate::test_utils::cairo_runner::{
4242
ValueArg,
4343
};
4444

45+
const COMPRESSION_MODULE_PATH: &str = "starkware.starknet.core.os.data_availability.compression";
46+
4547
/// Runs the OS compression function and returns the compressed data, plus the execution resources
4648
/// used to compress the data.
4749
fn cairo_compress(data: &[Felt]) -> (Vec<Felt>, ExecutionResources) {
@@ -54,7 +56,7 @@ fn cairo_compress(data: &[Felt]) -> (Vec<Felt>, ExecutionResources) {
5456
let (mut runner, program, entrypoint) = initialize_cairo_runner(
5557
&runner_config,
5658
OS_PROGRAM_BYTES,
57-
"starkware.starknet.core.os.data_availability.compression.compress",
59+
&format!("{COMPRESSION_MODULE_PATH}.compress"),
5860
std::slice::from_ref(&range_check_arg),
5961
HashMap::new(),
6062
)
@@ -115,6 +117,74 @@ fn cairo_compress(data: &[Felt]) -> (Vec<Felt>, ExecutionResources) {
115117
(compressed_data.into_iter().map(|f| *f).collect(), runner.get_execution_resources().unwrap())
116118
}
117119

120+
/// Runs the OS decompression function and returns the decompressed data.
121+
fn cairo_decompress(compressed: &[Felt]) -> Vec<Felt> {
122+
let range_check_arg = ImplicitArg::Builtin(BuiltinName::range_check);
123+
let runner_config = EntryPointRunnerConfig {
124+
layout: LayoutName::starknet,
125+
add_main_prefix_to_entrypoint: false,
126+
..Default::default()
127+
};
128+
let (mut runner, program, entrypoint) = initialize_cairo_runner(
129+
&runner_config,
130+
OS_PROGRAM_BYTES,
131+
&format!("{COMPRESSION_MODULE_PATH}.decompress"),
132+
std::slice::from_ref(&range_check_arg),
133+
HashMap::new(),
134+
)
135+
.unwrap();
136+
137+
// Function accepts destination pointer explicitly, and the compressed data pointer is passed
138+
// as an implicit argument (along with the range check pointer). A pointer to the end of the
139+
// decompressed data is returned as an explicit argument.
140+
let compressed_ptr = runner
141+
.vm
142+
.gen_arg(&compressed.iter().map(|x| MaybeRelocatable::Int(*x)).collect::<Vec<_>>())
143+
.unwrap()
144+
.get_relocatable()
145+
.unwrap();
146+
let decompressed_dst = runner.vm.add_memory_segment();
147+
let explicit_args = vec![EndpointArg::Value(ValueArg::Single(decompressed_dst.into()))];
148+
let implicit_args = vec![
149+
range_check_arg,
150+
ImplicitArg::NonBuiltin(EndpointArg::Value(ValueArg::Single(compressed_ptr.into()))),
151+
];
152+
// Dummy value, just to indicate to the runner that a return value is expected.
153+
let expected_explicit_return_values = vec![EndpointArg::from(Felt::ZERO)];
154+
155+
// Run the entrypoint.
156+
// The compressed data is stored in the segment starting at `compressed_dst`, the returned
157+
// implicit value is the end of the compressed data.
158+
let state_reader = None;
159+
let (_implicit_return_values, explicit_return_values, _hint_processor) =
160+
run_cairo_0_entrypoint(
161+
entrypoint,
162+
&explicit_args,
163+
&implicit_args,
164+
state_reader,
165+
&mut runner,
166+
&program,
167+
&runner_config,
168+
&expected_explicit_return_values,
169+
)
170+
.unwrap();
171+
172+
// The explicit return value should be the decompressed end pointer.
173+
assert_eq!(explicit_return_values.len(), 1);
174+
let EndpointArg::Value(ValueArg::Single(MaybeRelocatable::RelocatableValue(decompressed_end))) =
175+
explicit_return_values[0]
176+
else {
177+
panic!("Expected a single felt return value, got {:?}", explicit_return_values[0]);
178+
};
179+
180+
// Read the compressed data from the segment and return.
181+
let decompressed_data = runner
182+
.vm
183+
.get_integer_range(decompressed_dst, (decompressed_end - decompressed_dst).unwrap())
184+
.unwrap();
185+
decompressed_data.into_iter().map(|f| *f).collect()
186+
}
187+
118188
#[rstest]
119189
#[case::zero([false; 10], Felt::ZERO)]
120190
#[case::thousand(
@@ -391,6 +461,6 @@ fn test_cairo_compress(#[case] data: Vec<Felt>, #[case] expected_n_steps_per_elm
391461
.assert_debug_eq(&(execution_resources.n_steps / data.len()));
392462
}
393463

464+
assert_eq!(data, cairo_decompress(&compressed));
394465
assert_eq!(data, decompress(&mut compressed.into_iter()));
395-
// TODO(Dori): Check cairo decompression.
396466
}

0 commit comments

Comments
 (0)