11use std:: collections:: HashMap ;
22use std:: sync:: LazyLock ;
33
4- use apollo_starknet_os_program:: AGGREGATOR_PROGRAM ;
4+ use apollo_starknet_os_program:: { AGGREGATOR_PROGRAM , OS_PROGRAM_BYTES } ;
55use ark_bls12_381:: Fr ;
66use cairo_vm:: types:: builtin_name:: BuiltinName ;
77use cairo_vm:: types:: layout_name:: LayoutName ;
8+ use cairo_vm:: types:: relocatable:: MaybeRelocatable ;
89use cairo_vm:: vm:: runners:: cairo_pie:: {
910 BuiltinAdditionalData ,
1011 OutputBuiltinAdditionalData ,
@@ -26,6 +27,11 @@ use crate::hint_processor::aggregator_hint_processor::{
2627 AggregatorInput ,
2728 DataAvailability ,
2829} ;
30+ use crate :: hints:: hint_implementation:: aggregator:: utils:: {
31+ write_full_os_output,
32+ FullOsOutputsData ,
33+ FullStateDiffWriter ,
34+ } ;
2935use crate :: hints:: hint_implementation:: kzg:: utils:: {
3036 polynomial_coefficients_to_kzg_commitment,
3137 BLS_PRIME ,
@@ -36,9 +42,18 @@ use crate::io::os_input::OsChainInfo;
3642use crate :: io:: os_output_types:: {
3743 FullContractChanges ,
3844 FullContractStorageUpdate ,
45+ TryFromOutputIter ,
3946 N_UPDATES_SMALL_PACKING_BOUND ,
4047} ;
4148use crate :: runner:: { run_program, RunnerReturnObject } ;
49+ use crate :: test_utils:: cairo_runner:: {
50+ initialize_cairo_runner,
51+ run_cairo_0_entrypoint,
52+ EndpointArg ,
53+ EntryPointRunnerConfig ,
54+ ImplicitArg ,
55+ ValueArg ,
56+ } ;
4257use crate :: test_utils:: validations:: validate_builtins;
4358
4459// Dummy values for the test.
@@ -628,6 +643,94 @@ fn bootloader_output(full_output: bool, modifier: FailureModifier) -> Vec<Felt>
628643 . concat ( )
629644}
630645
646+ #[ rstest]
647+ fn test_parse_and_output (
648+ #[ values( 0 , 1 ) ] block_idx : usize ,
649+ #[ values( false , true ) ] full_output_result : bool ,
650+ ) {
651+ // Prepare input.
652+ let full_output = true ;
653+ let bootloader_output_data = bootloader_output ( full_output, FailureModifier :: None ) ;
654+ let FullOsOutputsData { outputs, n_outputs, .. } =
655+ FullOsOutputsData :: try_from_output_iter ( & mut bootloader_output_data. into_iter ( ) , None )
656+ . unwrap ( ) ;
657+ assert_eq ! ( n_outputs, 2 ) ;
658+ let os_output = & outputs. 0 [ block_idx] ;
659+
660+ // Initialize runner.
661+ let output_arg = ImplicitArg :: Builtin ( BuiltinName :: output) ;
662+ let range_check_arg = ImplicitArg :: Builtin ( BuiltinName :: range_check) ;
663+ let ec_op_arg = ImplicitArg :: Builtin ( BuiltinName :: ec_op) ;
664+ let poseidon_arg = ImplicitArg :: Builtin ( BuiltinName :: poseidon) ;
665+ let implicit_args = [ output_arg, range_check_arg, ec_op_arg, poseidon_arg] ;
666+ let runner_config = EntryPointRunnerConfig {
667+ layout : LayoutName :: starknet,
668+ add_main_prefix_to_entrypoint : false ,
669+ ..Default :: default ( )
670+ } ;
671+ let ( mut runner, program, entrypoint) = initialize_cairo_runner (
672+ & runner_config,
673+ OS_PROGRAM_BYTES ,
674+ "starkware.starknet.core.os.output.serialize_os_output" ,
675+ & implicit_args,
676+ HashMap :: new ( ) ,
677+ )
678+ . unwrap ( ) ;
679+ let runner = & mut runner;
680+ let vm = & mut runner. vm ;
681+
682+ // Write the input (OS output) to the VM memory.
683+ let os_output_segment = vm. add_memory_segment ( ) ;
684+ let diff_writer = & mut FullStateDiffWriter :: new ( vm) ;
685+ write_full_os_output ( os_output, vm, os_output_segment, diff_writer, full_output_result)
686+ . unwrap ( ) ;
687+
688+ // Write public keys (empty list) to the VM memory.
689+ let public_keys: Vec < MaybeRelocatable > = vec ! [ ] ;
690+ let public_keys_segment = vm. add_memory_segment ( ) ;
691+ vm. write_arg ( public_keys_segment, & public_keys) . unwrap ( ) ;
692+
693+ // Prepare explicit args.
694+ let replace_keys_with_aliases = Felt :: from ( false ) ;
695+ let n_public_keys = Felt :: from ( public_keys. len ( ) ) ;
696+ let explicit_args = vec ! [
697+ EndpointArg :: Value ( ValueArg :: Single ( os_output_segment. into( ) ) ) ,
698+ EndpointArg :: Value ( ValueArg :: Single ( replace_keys_with_aliases. into( ) ) ) ,
699+ EndpointArg :: Value ( ValueArg :: Single ( n_public_keys. into( ) ) ) ,
700+ EndpointArg :: Value ( ValueArg :: Single ( public_keys_segment. into( ) ) ) ,
701+ ] ;
702+
703+ // Run the entrypoint.
704+ let state_reader = None ;
705+ let expected_explicit_return_values = [ ] ;
706+ let ( implicit_return_values, _explicit_return_values, _hint_processor) =
707+ run_cairo_0_entrypoint (
708+ entrypoint,
709+ & explicit_args,
710+ & implicit_args,
711+ state_reader,
712+ runner,
713+ & program,
714+ & runner_config,
715+ & expected_explicit_return_values,
716+ )
717+ . unwrap ( ) ;
718+
719+ // Verify the output is as expected.
720+ let [ EndpointArg :: Value ( ValueArg :: Array ( output_array) ) , _rc, _ec, _poseidon] =
721+ implicit_return_values. as_slice ( )
722+ else {
723+ panic ! ( "Unexpected implicit return value structure, got: {implicit_return_values:?}." ) ;
724+ } ;
725+ let output_array = output_array. iter ( ) . map ( |f| f. get_int ( ) . unwrap ( ) ) . collect :: < Vec < Felt > > ( ) ;
726+ if block_idx == 0 {
727+ assert_eq ! ( output_array, multi_block0_output( full_output_result) ) ;
728+ } else {
729+ assert_eq ! ( block_idx, 1 ) ;
730+ assert_eq ! ( output_array, multi_block1_output( full_output_result, FailureModifier :: None ) ) ;
731+ }
732+ }
733+
631734#[ rstest]
632735#[ case( false , false , FailureModifier :: None , None ) ]
633736#[ case( true , false , FailureModifier :: None , None ) ]
0 commit comments