@@ -133,6 +133,7 @@ pub struct BusinessLogicSyscallHandler<'a, S: StateReader> {
133133 pub ( crate ) support_reverted : bool ,
134134 pub ( crate ) entry_point_selector : Felt252 ,
135135 pub ( crate ) selector_to_syscall : & ' a HashMap < Felt252 , & ' static str > ,
136+ pub ( crate ) execution_info_ptr : Option < Relocatable > ,
136137}
137138
138139// TODO: execution entry point may no be a parameter field, but there is no way to generate a default for now
@@ -171,6 +172,7 @@ impl<'a, S: StateReader> BusinessLogicSyscallHandler<'a, S> {
171172 support_reverted,
172173 entry_point_selector,
173174 selector_to_syscall : & SELECTOR_TO_SYSCALL ,
175+ execution_info_ptr : None ,
174176 }
175177 }
176178 pub fn default_with_state ( state : & ' a mut CachedState < S > ) -> Self {
@@ -227,6 +229,7 @@ impl<'a, S: StateReader> BusinessLogicSyscallHandler<'a, S> {
227229 support_reverted : false ,
228230 entry_point_selector,
229231 selector_to_syscall : & SELECTOR_TO_SYSCALL ,
232+ execution_info_ptr : None ,
230233 }
231234 }
232235
@@ -533,10 +536,10 @@ impl<'a, S: StateReader> BusinessLogicSyscallHandler<'a, S> {
533536 /// them as accessed.
534537 pub ( crate ) fn validate_read_only_segments (
535538 & self ,
536- runner : & mut VirtualMachine ,
539+ vm : & mut VirtualMachine ,
537540 ) -> Result < ( ) , TransactionError > {
538541 for ( segment_ptr, segment_size) in self . read_only_segments . clone ( ) {
539- let used_size = runner
542+ let used_size = vm
540543 . get_segment_used_size ( segment_ptr. segment_index as usize )
541544 . ok_or ( TransactionError :: InvalidSegmentSize ) ?;
542545
@@ -548,7 +551,7 @@ impl<'a, S: StateReader> BusinessLogicSyscallHandler<'a, S> {
548551 if seg_size != used_size. into ( ) {
549552 return Err ( TransactionError :: OutOfBound ) ;
550553 }
551- runner . mark_address_range_as_accessed ( segment_ptr, used_size) ?;
554+ vm . mark_address_range_as_accessed ( segment_ptr, used_size) ?;
552555 }
553556 Ok ( ( ) )
554557 }
@@ -625,63 +628,69 @@ impl<'a, S: StateReader> BusinessLogicSyscallHandler<'a, S> {
625628 } )
626629 }
627630
631+ // Returns the pointer to the segment with the execution info if it was already written.
632+ // If it wasn't, it writes the execution info into memory and returns its start address.
633+ fn get_or_allocate_execution_info (
634+ & mut self ,
635+ vm : & mut VirtualMachine ,
636+ ) -> Result < Relocatable , SyscallHandlerError > {
637+ if let Some ( ptr) = self . execution_info_ptr {
638+ return Ok ( ptr) ;
639+ }
640+
641+ // Allocate block_info
642+ let block_info = & self . block_context . block_info ;
643+ let block_info_data = vec ! [
644+ MaybeRelocatable :: from( Felt252 :: from( block_info. block_number) ) ,
645+ MaybeRelocatable :: from( Felt252 :: from( block_info. block_timestamp) ) ,
646+ MaybeRelocatable :: from( & block_info. sequencer_address. 0 ) ,
647+ ] ;
648+ let block_info_ptr = self . allocate_segment ( vm, block_info_data) ?;
649+
650+ // Allocate signature
651+ let signature: Vec < MaybeRelocatable > = self
652+ . tx_execution_context
653+ . signature
654+ . iter ( )
655+ . map ( MaybeRelocatable :: from)
656+ . collect ( ) ;
657+ let signature_start_ptr = self . allocate_segment ( vm, signature) ?;
658+ let signature_end_ptr = ( signature_start_ptr + self . tx_execution_context . signature . len ( ) ) ?;
659+
660+ // Allocate tx info
661+ let tx_info = & self . tx_execution_context ;
662+ let tx_info_data = vec ! [
663+ MaybeRelocatable :: from( & tx_info. version) ,
664+ MaybeRelocatable :: from( & tx_info. account_contract_address. 0 ) ,
665+ MaybeRelocatable :: from( Felt252 :: from( tx_info. max_fee) ) ,
666+ signature_start_ptr. into( ) ,
667+ signature_end_ptr. into( ) ,
668+ MaybeRelocatable :: from( & tx_info. transaction_hash) ,
669+ MaybeRelocatable :: from( & self . block_context. starknet_os_config. chain_id) ,
670+ MaybeRelocatable :: from( & tx_info. nonce) ,
671+ ] ;
672+ let tx_info_ptr = self . allocate_segment ( vm, tx_info_data) ?;
673+
674+ // Allocate execution_info
675+ let execution_info = vec ! [
676+ block_info_ptr. into( ) ,
677+ tx_info_ptr. into( ) ,
678+ MaybeRelocatable :: from( & self . caller_address. 0 ) ,
679+ MaybeRelocatable :: from( & self . contract_address. 0 ) ,
680+ MaybeRelocatable :: from( & self . entry_point_selector) ,
681+ ] ;
682+ let execution_info_ptr = self . allocate_segment ( vm, execution_info) ?;
683+
684+ self . execution_info_ptr = Some ( execution_info_ptr) ;
685+ Ok ( execution_info_ptr)
686+ }
687+
628688 fn get_execution_info (
629- & self ,
689+ & mut self ,
630690 vm : & mut VirtualMachine ,
631691 remaining_gas : u128 ,
632692 ) -> Result < SyscallResponse , SyscallHandlerError > {
633- let tx_info = & self . tx_execution_context ;
634- let block_info = & self . block_context . block_info ;
635-
636- let mut res_segment = vm. add_memory_segment ( ) ;
637-
638- let signature_start = res_segment;
639- for s in tx_info. signature . iter ( ) {
640- vm. insert_value ( res_segment, s) ?;
641- res_segment = ( res_segment + 1 ) ?;
642- }
643- let signature_end = res_segment;
644-
645- let tx_info_ptr = res_segment;
646- vm. insert_value :: < Felt252 > ( res_segment, tx_info. version . clone ( ) ) ?;
647- res_segment = ( res_segment + 1 ) ?;
648- vm. insert_value ( res_segment, tx_info. account_contract_address . 0 . clone ( ) ) ?;
649- res_segment = ( res_segment + 1 ) ?;
650- vm. insert_value :: < Felt252 > ( res_segment, tx_info. max_fee . into ( ) ) ?;
651- res_segment = ( res_segment + 1 ) ?;
652- vm. insert_value ( res_segment, signature_start) ?;
653- res_segment = ( res_segment + 1 ) ?;
654- vm. insert_value ( res_segment, signature_end) ?;
655- res_segment = ( res_segment + 1 ) ?;
656- vm. insert_value ( res_segment, tx_info. transaction_hash . clone ( ) ) ?;
657- res_segment = ( res_segment + 1 ) ?;
658- vm. insert_value :: < Felt252 > (
659- res_segment,
660- self . block_context . starknet_os_config . chain_id . clone ( ) ,
661- ) ?;
662- res_segment = ( res_segment + 1 ) ?;
663- vm. insert_value :: < Felt252 > ( res_segment, tx_info. nonce . clone ( ) ) ?;
664- res_segment = ( res_segment + 1 ) ?;
665-
666- let block_info_ptr = res_segment;
667- vm. insert_value :: < Felt252 > ( res_segment, block_info. block_number . into ( ) ) ?;
668- res_segment = ( res_segment + 1 ) ?;
669- vm. insert_value :: < Felt252 > ( res_segment, block_info. block_timestamp . into ( ) ) ?;
670- res_segment = ( res_segment + 1 ) ?;
671- vm. insert_value :: < Felt252 > ( res_segment, block_info. sequencer_address . 0 . clone ( ) ) ?;
672- res_segment = ( res_segment + 1 ) ?;
673-
674- let exec_info_ptr = res_segment;
675- vm. insert_value ( res_segment, block_info_ptr) ?;
676- res_segment = ( res_segment + 1 ) ?;
677- vm. insert_value ( res_segment, tx_info_ptr) ?;
678- res_segment = ( res_segment + 1 ) ?;
679- vm. insert_value :: < Felt252 > ( res_segment, self . caller_address . 0 . clone ( ) ) ?;
680- res_segment = ( res_segment + 1 ) ?;
681- vm. insert_value :: < Felt252 > ( res_segment, self . contract_address . 0 . clone ( ) ) ?;
682- res_segment = ( res_segment + 1 ) ?;
683- vm. insert_value :: < Felt252 > ( res_segment, self . entry_point_selector . clone ( ) ) ?;
684-
693+ let exec_info_ptr = self . get_or_allocate_execution_info ( vm) ?;
685694 Ok ( SyscallResponse {
686695 gas : remaining_gas,
687696 body : Some ( ResponseBody :: GetExecutionInfo { exec_info_ptr } ) ,
0 commit comments