-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8d8ec18
commit 61435d3
Showing
4 changed files
with
131 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub mod entry_point_execution; | ||
pub mod syscall_handler; | ||
pub mod utils; | ||
|
||
|
111 changes: 111 additions & 0 deletions
111
crates/blockifier/src/execution/native/entry_point_execution.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
use std::collections::HashMap; | ||
|
||
use cairo_lang_sierra::ids::FunctionId; | ||
use cairo_native::execution_result::ContractExecutionResult; | ||
use cairo_native::executor::AotNativeExecutor; | ||
use cairo_vm::vm::runners::cairo_runner::ExecutionResources; | ||
|
||
use super::utils::decode_felts_as_str; | ||
// use c::utils::run_native_executor; | ||
use crate::execution::call_info::{CallExecution, CallInfo, Retdata}; | ||
use crate::execution::contract_class::{NativeContractClassV1, TrackedResource}; | ||
use crate::execution::entry_point::{ | ||
CallEntryPoint, | ||
EntryPointExecutionContext, | ||
EntryPointExecutionResult, | ||
}; | ||
use crate::execution::errors::EntryPointExecutionError; | ||
use crate::execution::native::syscall_handler::NativeSyscallHandler; | ||
use crate::state::state_api::State; | ||
|
||
pub fn execute_entry_point_call( | ||
call: CallEntryPoint, | ||
contract_class: NativeContractClassV1, | ||
state: &mut dyn State, | ||
resources: &mut ExecutionResources, | ||
context: &mut EntryPointExecutionContext, | ||
) -> EntryPointExecutionResult<CallInfo> { | ||
let function_id = contract_class.get_entry_point(&call)?; | ||
|
||
let syscall_handler: NativeSyscallHandler<'_> = NativeSyscallHandler::new( | ||
state, | ||
call.caller_address, | ||
call.storage_address, | ||
call.entry_point_selector, | ||
resources, | ||
context, | ||
); | ||
|
||
run_native_executor(&contract_class.executor, function_id, call, syscall_handler) | ||
} | ||
|
||
fn run_native_executor( | ||
native_executor: &AotNativeExecutor, | ||
function_id: &FunctionId, | ||
call: CallEntryPoint, | ||
mut syscall_handler: NativeSyscallHandler<'_>, | ||
) -> EntryPointExecutionResult<CallInfo> { | ||
let execution_result = native_executor.invoke_contract_dynamic( | ||
function_id, | ||
&call.calldata.0, | ||
Some(call.initial_gas.into()), | ||
&mut syscall_handler, | ||
); | ||
|
||
let run_result = match execution_result { | ||
Err(runner_err) => { | ||
Err(EntryPointExecutionError::NativeUnexpectedError { source: runner_err }) | ||
} | ||
Ok(res) if res.failure_flag => Err(EntryPointExecutionError::NativeExecutionError { | ||
info: if !res.return_values.is_empty() { | ||
decode_felts_as_str(&res.return_values) | ||
} else { | ||
String::from("Unknown error") | ||
}, | ||
}), | ||
Ok(res) => Ok(res), | ||
}?; | ||
|
||
create_callinfo(call.clone(), run_result, syscall_handler) | ||
} | ||
|
||
fn create_callinfo( | ||
call: CallEntryPoint, | ||
run_result: ContractExecutionResult, | ||
syscall_handler: NativeSyscallHandler<'_>, | ||
) -> Result<CallInfo, EntryPointExecutionError> { | ||
let gas_consumed = { | ||
// We can use `.unwrap()` directly in both cases because the most significant bit is could | ||
// be only 63 here (128 = 64 + 64). | ||
let low: u64 = (run_result.remaining_gas & ((1u128 << 64) - 1)).try_into().unwrap(); | ||
let high: u64 = (run_result.remaining_gas >> 64).try_into().unwrap(); | ||
if high != 0 { | ||
return Err(EntryPointExecutionError::NativeExecutionError { | ||
info: "Overflow: gas consumed bigger than 64 bit".into(), | ||
}); | ||
} | ||
call.initial_gas - low | ||
}; | ||
|
||
Ok(CallInfo { | ||
call, | ||
execution: CallExecution { | ||
retdata: Retdata(run_result.return_values), | ||
events: syscall_handler.events, | ||
l2_to_l1_messages: syscall_handler.l2_to_l1_messages, | ||
failed: run_result.failure_flag, | ||
gas_consumed, | ||
}, | ||
// todo(rodrigo): execution resources rely heavily on how the VM work, therefore | ||
// the dummy values | ||
resources: ExecutionResources { | ||
n_steps: 0, | ||
n_memory_holes: 0, | ||
builtin_instance_counter: HashMap::default(), | ||
}, | ||
inner_calls: syscall_handler.inner_calls, | ||
storage_read_values: syscall_handler.read_values, | ||
accessed_storage_keys: syscall_handler.accessed_keys, | ||
tracked_resource: TrackedResource::SierraGas, | ||
}) | ||
} |