@@ -3,6 +3,7 @@ use std::rc::Rc;
33
44use super :: syscall_request:: * ;
55use crate :: business_logic:: execution:: objects:: * ;
6+ use crate :: business_logic:: execution:: state:: ExecutionResourcesManager ;
67use crate :: core:: errors:: syscall_handler_errors:: SyscallHandlerError ;
78use crate :: core:: syscalls:: syscall_handler:: SyscallHandler ;
89use crate :: hash_utils:: calculate_contract_address_from_hash;
@@ -18,7 +19,11 @@ use num_traits::{One, Zero};
1819
1920pub struct BusinessLogicSyscallHandler {
2021 tx_execution_context : Rc < RefCell < TransactionExecutionContext > > ,
22+ /// Events emitted by the current contract call.
2123 events : Rc < RefCell < Vec < OrderedEvent > > > ,
24+ /// A list of dynamically allocated segments that are expected to be read-only.
25+ read_only_segments : Rc < RefCell < Vec < ( Relocatable , MaybeRelocatable ) > > > ,
26+ resources_manager : Rc < RefCell < ExecutionResourcesManager > > ,
2227 contract_address : u64 ,
2328 l2_to_l1_messages : Vec < OrderedL2ToL1Message > ,
2429}
@@ -27,18 +32,24 @@ impl BusinessLogicSyscallHandler {
2732 pub fn new ( ) -> Self {
2833 let events = Rc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
2934 let tx_execution_context = Rc :: new ( RefCell :: new ( TransactionExecutionContext :: new ( ) ) ) ;
35+ let read_only_segments = Rc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
36+ let resources_manager = Rc :: new ( RefCell :: new ( ExecutionResourcesManager :: default ( ) ) ) ;
37+
3038 BusinessLogicSyscallHandler {
3139 events,
3240 tx_execution_context,
41+ read_only_segments,
42+ resources_manager,
3343 contract_address : 0 ,
3444 l2_to_l1_messages : Vec :: new ( ) ,
3545 }
3646 }
37- }
3847
39- impl Default for BusinessLogicSyscallHandler {
40- fn default ( ) -> Self {
41- Self :: new ( )
48+ /// Increments the syscall count for a given `syscall_name` by 1.
49+ fn increment_syscall_count ( & self , syscall_name : & str ) {
50+ self . resources_manager
51+ . borrow_mut ( )
52+ . increment_syscall_counter ( syscall_name, 1 ) ;
4253 }
4354}
4455
@@ -159,6 +170,7 @@ impl SyscallHandler for BusinessLogicSyscallHandler {
159170 vm : & VirtualMachine ,
160171 syscall_ptr : Relocatable ,
161172 ) -> Result < SyscallRequest , SyscallHandlerError > {
173+ self . increment_syscall_count ( syscall_name) ;
162174 self . read_syscall_request ( syscall_name, vm, syscall_ptr)
163175 }
164176
@@ -205,9 +217,25 @@ impl SyscallHandler for BusinessLogicSyscallHandler {
205217 fn _storage_write ( & self , _address : i32 , _value : i32 ) {
206218 todo ! ( )
207219 }
208- fn _allocate_segment ( & self , _vm : VirtualMachine , _data : Vec < MaybeRelocatable > ) -> Relocatable {
209- todo ! ( )
220+
221+ fn allocate_segment (
222+ & self ,
223+ vm : & mut VirtualMachine ,
224+ data : Vec < MaybeRelocatable > ,
225+ ) -> Result < Relocatable , SyscallHandlerError > {
226+ let segment_start = vm. add_memory_segment ( ) ;
227+ let segment_end = vm
228+ . write_arg ( & segment_start, & data)
229+ . map_err ( |_| SyscallHandlerError :: SegmentationFault ) ?;
230+ let sub = segment_end
231+ . sub ( & segment_start. to_owned ( ) . into ( ) , vm. get_prime ( ) )
232+ . map_err ( |_| SyscallHandlerError :: SegmentationFault ) ?;
233+ let segment = ( segment_start. to_owned ( ) , sub) ;
234+ self . read_only_segments . borrow_mut ( ) . push ( segment) ;
235+
236+ Ok ( segment_start)
210237 }
238+
211239 fn _write_syscall_response (
212240 & self ,
213241 _response : Vec < i32 > ,
@@ -218,6 +246,12 @@ impl SyscallHandler for BusinessLogicSyscallHandler {
218246 }
219247}
220248
249+ impl Default for BusinessLogicSyscallHandler {
250+ fn default ( ) -> Self {
251+ Self :: new ( )
252+ }
253+ }
254+
221255#[ cfg( test) ]
222256mod tests {
223257 use crate :: bigint;
@@ -384,6 +418,21 @@ mod tests {
384418 )
385419 }
386420
421+ #[ test]
422+ fn can_allocate_segment ( ) {
423+ let mut syscall_handler = BusinessLogicSyscallHandler :: new ( ) ;
424+ let mut vm = vm ! ( ) ;
425+ let data = vec ! [ MaybeRelocatable :: Int ( 7 . into( ) ) ] ;
426+
427+ let segment_start = syscall_handler. allocate_segment ( & mut vm, data) . unwrap ( ) ;
428+ let expected_value = vm
429+ . get_integer ( & Relocatable :: from ( ( 0 , 0 ) ) )
430+ . unwrap ( )
431+ . into_owned ( ) ;
432+ assert_eq ! ( Relocatable :: from( ( 0 , 0 ) ) , segment_start) ;
433+ assert_eq ! ( expected_value, 7 . into( ) ) ;
434+ }
435+
387436 #[ test]
388437 fn test_send_message_to_l1_ok ( ) {
389438 let mut syscall = BusinessLogicSyscallHandler :: new ( ) ;
0 commit comments