Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(blockifier): add read and write cairo native syscalls #1305

Merged
merged 2 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 53 additions & 12 deletions crates/blockifier/src/execution/native/syscall_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ use cairo_native::starknet::{
SyscallResult,
U256,
};
use cairo_native::starknet_stub::encode_str_as_felts;
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use starknet_api::state::StorageKey;
use starknet_types_core::felt::Felt;

use crate::execution::call_info::{CallInfo, OrderedEvent, OrderedL2ToL1Message, Retdata};
use crate::execution::entry_point::{CallEntryPoint, EntryPointExecutionContext};
use crate::execution::native::utils::encode_str_as_felts;
use crate::execution::syscalls::hint_processor::{SyscallCounter, OUT_OF_GAS_ERROR};
use crate::execution::syscalls::hint_processor::{
SyscallCounter,
SyscallExecutionError,
OUT_OF_GAS_ERROR,
};
use crate::execution::syscalls::SyscallSelector;
use crate::state::state_api::State;

Expand Down Expand Up @@ -96,7 +100,6 @@ impl<'state> NativeSyscallHandler<'state> {

/// Handles all gas-related logics and additional metadata such as `SyscallCounter`. In native,
/// we need to explicitly call this method at the beginning of each syscall.
#[allow(dead_code)]
fn pre_execute_syscall(
&mut self,
remaining_gas: &mut u128,
Expand Down Expand Up @@ -183,21 +186,59 @@ impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> {

fn storage_read(
&mut self,
_address_domain: u32,
_address: Felt,
_remaining_gas: &mut u128,
address_domain: u32,
address: Felt,
remaining_gas: &mut u128,
) -> SyscallResult<Felt> {
todo!("Implement storage_read syscall.");
self.pre_execute_syscall(
remaining_gas,
SyscallSelector::StorageRead,
self.context.gas_costs().storage_read_gas_cost,
)?;

if address_domain != 0 {
let address_domain = Felt::from(address_domain);
let err = SyscallExecutionError::InvalidAddressDomain { address_domain };
return Err(encode_str_as_felts(&err.to_string()));
}

let key = StorageKey::try_from(address).map_err(|e| encode_str_as_felts(&e.to_string()))?;

let read_result = self.state.get_storage_at(self.call.storage_address, key);
let value = read_result.map_err(|e| encode_str_as_felts(&e.to_string()))?;

self.accessed_keys.insert(key);
self.read_values.push(value);

Ok(value)
}

fn storage_write(
&mut self,
_address_domain: u32,
_address: Felt,
_value: Felt,
_remaining_gas: &mut u128,
address_domain: u32,
address: Felt,
value: Felt,
remaining_gas: &mut u128,
) -> SyscallResult<()> {
todo!("Implement storage_write syscall.");
self.pre_execute_syscall(
remaining_gas,
SyscallSelector::StorageWrite,
self.context.gas_costs().storage_write_gas_cost,
)?;

if address_domain != 0 {
let address_domain = Felt::from(address_domain);
let err = SyscallExecutionError::InvalidAddressDomain { address_domain };
return Err(encode_str_as_felts(&err.to_string()));
}

let key = StorageKey::try_from(address).map_err(|e| encode_str_as_felts(&e.to_string()))?;
self.accessed_keys.insert(key);

let write_result = self.state.set_storage_at(self.call.storage_address, key, value);
write_result.map_err(|e| encode_str_as_felts(&e.to_string()))?;

Ok(())
}

fn emit_event(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ use crate::test_utils::contracts::FeatureContract;
use crate::test_utils::initial_test_state::test_state;
use crate::test_utils::{trivial_external_entry_point_new, CairoVersion, BALANCE};

#[cfg_attr(
feature = "cairo_native",
test_case(FeatureContract::TestContract(CairoVersion::Native), 27290; "Native")
)]
#[test_case(FeatureContract::TestContract(CairoVersion::Cairo1), REQUIRED_GAS_STORAGE_READ_WRITE_TEST; "VM")]
fn test_storage_read_write(test_contract: FeatureContract, expected_gas: u64) {
let chain_info = &ChainInfo::create_for_testing();
Expand Down
Loading