Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Add skeleton for the get_block_hash syscall.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArniStarkware committed Jun 7, 2023
1 parent 7fd6850 commit 3524621
Show file tree
Hide file tree
Showing 9 changed files with 2,290 additions and 1,651 deletions.

Large diffs are not rendered by default.

2,977 changes: 1,540 additions & 1,437 deletions crates/blockifier/feature_contracts/cairo1/compiled/test_contract.sierra.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ mod TestContract {
use array::SpanTrait;
use clone::Clone;
use traits::Into;
use traits::TryInto;
use option::OptionTrait;

const UNEXPECTED_ERROR: felt252 = 'UNEXPECTED ERROR';

Expand Down Expand Up @@ -48,6 +50,13 @@ mod TestContract {
starknet::syscalls::emit_event_syscall(keys.span(), data.span()).unwrap_syscall();
}

#[starknet::external]
fn test_get_block_hash(self: @Storage, block_number_as_felt: felt252) -> felt252 {
starknet::syscalls::get_block_hash_syscall(
block_number_as_felt.try_into().unwrap()
).unwrap_syscall()
}

#[starknet::external]
fn test_get_execution_info(
self: @Storage,
Expand Down
5 changes: 5 additions & 0 deletions crates/blockifier/src/abi/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ pub const N_STEPS_RESOURCE: &str = "n_steps";
// Casm hash calculation-related constants.
pub const CAIRO0_ENTRY_POINT_STRUCT_SIZE: usize = 2;
pub const N_STEPS_PER_PEDERSEN: usize = 8;

// OS reserved contract addresses.

// This contract stores the block number -> block hash mapping.
pub const BLOCK_HASH_CONTRACT_ADDRESS: u64 = 0x1;
2 changes: 2 additions & 0 deletions crates/blockifier/src/execution/deprecated_syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub enum DeprecatedSyscallSelector {
DelegateL1Handler,
Deploy,
EmitEvent,
GetBlockHash,
GetBlockNumber,
GetBlockTimestamp,
GetCallerAddress,
Expand Down Expand Up @@ -70,6 +71,7 @@ impl TryFrom<StarkFelt> for DeprecatedSyscallSelector {
b"DelegateL1Handler" => Ok(Self::DelegateL1Handler),
b"Deploy" => Ok(Self::Deploy),
b"EmitEvent" => Ok(Self::EmitEvent),
b"GetBlockHash" => Ok(Self::GetBlockHash),
b"GetBlockNumber" => Ok(Self::GetBlockNumber),
b"GetBlockTimestamp" => Ok(Self::GetBlockTimestamp),
b"GetCallerAddress" => Ok(Self::GetCallerAddress),
Expand Down
9 changes: 5 additions & 4 deletions crates/blockifier/src/execution/syscalls/hint_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ use crate::execution::execution_utils::{
ReadOnlySegment, ReadOnlySegments,
};
use crate::execution::syscalls::{
call_contract, deploy, emit_event, get_execution_info, library_call, library_call_l1_handler,
replace_class, send_message_to_l1, storage_read, storage_write, StorageReadResponse,
StorageWriteResponse, SyscallRequest, SyscallRequestWrapper, SyscallResponse,
SyscallResponseWrapper, SyscallResult, SyscallSelector,
call_contract, deploy, emit_event, get_block_hash, get_execution_info, library_call,
library_call_l1_handler, replace_class, send_message_to_l1, storage_read, storage_write,
StorageReadResponse, StorageWriteResponse, SyscallRequest, SyscallRequestWrapper,
SyscallResponse, SyscallResponseWrapper, SyscallResult, SyscallSelector,
};
use crate::state::errors::StateError;
use crate::state::state_api::State;
Expand Down Expand Up @@ -174,6 +174,7 @@ impl<'a> SyscallHintProcessor<'a> {
SyscallSelector::CallContract => self.execute_syscall(vm, call_contract),
SyscallSelector::Deploy => self.execute_syscall(vm, deploy),
SyscallSelector::EmitEvent => self.execute_syscall(vm, emit_event),
SyscallSelector::GetBlockHash => self.execute_syscall(vm, get_block_hash),
SyscallSelector::GetExecutionInfo => self.execute_syscall(vm, get_execution_info),
SyscallSelector::LibraryCall => self.execute_syscall(vm, library_call),
SyscallSelector::LibraryCallL1Handler => {
Expand Down
47 changes: 47 additions & 0 deletions crates/blockifier/src/execution/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use self::hint_processor::{
read_call_params, read_calldata, read_felt_array, write_segment, SyscallExecutionError,
SyscallHintProcessor,
};
use crate::abi::constants;
use crate::execution::deprecated_syscalls::DeprecatedSyscallSelector;
use crate::execution::entry_point::{
CallEntryPoint, CallType, MessageToL1, OrderedEvent, OrderedL2ToL1Message,
Expand Down Expand Up @@ -272,6 +273,52 @@ pub fn emit_event(
Ok(EmitEventResponse {})
}

// GetBlockHash syscall.

#[derive(Debug, Eq, PartialEq)]

// TODO(Arni, 8/6/2023): Consider replacing with block_number: u64.
pub struct GetBlockHashRequest {
pub block_number: StarkFelt,
}

impl SyscallRequest for GetBlockHashRequest {
fn read(vm: &VirtualMachine, ptr: &mut Relocatable) -> SyscallResult<GetBlockHashRequest> {
let block_number = stark_felt_from_ptr(vm, ptr)?;
Ok(GetBlockHashRequest { block_number })
}
}

#[derive(Debug, Eq, PartialEq)]
pub struct GetBlockHashResponse {
pub block_hash: StarkFelt,
}

impl SyscallResponse for GetBlockHashResponse {
fn write(self, vm: &mut VirtualMachine, ptr: &mut Relocatable) -> WriteResponseResult {
write_stark_felt(vm, ptr, self.block_hash)?;
Ok(())
}
}

// Returns the block hash of the block at given block_number.
// Raises an error if latest - block_number < 10.
// Returns the expected block hash if 10 <= latest - block_number < 1024.
// Returns unexpected value, otherwise (Most likly - returns an uninitialized value = 0).
// TODO(Arni, 11/6/2023): Implement according to the documentation above.
pub fn get_block_hash(
request: GetBlockHashRequest,
_vm: &mut VirtualMachine,
syscall_handler: &mut SyscallHintProcessor<'_>,
) -> SyscallResult<GetBlockHashResponse> {
let key = StorageKey::try_from(request.block_number)?;
let contract_address =
ContractAddress::try_from(StarkFelt::from(constants::BLOCK_HASH_CONTRACT_ADDRESS))?;
let block_hash = syscall_handler.state.get_storage_at(contract_address, key)?;

Ok(GetBlockHashResponse { block_hash })
}

// GetExecutionInfo syscall.

type GetExecutionInfoRequest = EmptyRequest;
Expand Down
20 changes: 20 additions & 0 deletions crates/blockifier/src/execution/syscalls/syscalls_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,26 @@ fn test_emit_event() {
);
}

// TODO(Arni, 11/6/2023): Initialize the "contract" at BLOCK_HASH_CONTRACT_ADDRESS.
#[test]
fn test_get_block_hash() {
let mut state = create_test_state();

let calldata = calldata![
stark_felt!(1800_u64) // Block number.
];
let entry_point_call = CallEntryPoint {
entry_point_selector: selector_from_name("test_get_block_hash"),
calldata,
..trivial_external_entry_point()
};

assert_eq!(
entry_point_call.execute_directly(&mut state).unwrap().execution,
CallExecution::from_retdata(retdata![stark_felt!(0_u8)])
);
}

#[test]
fn test_get_execution_info() {
let mut state = create_test_state();
Expand Down
5 changes: 5 additions & 0 deletions crates/blockifier/src/fee/os_resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ fn os_resources() -> serde_json::Value {
"n_memory_holes": 0,
"n_steps": 19
},
"GetBlockHash": {
"builtin_instance_counter": {},
"n_memory_holes": 0,
"n_steps": 0
},
"GetBlockNumber": {
"builtin_instance_counter": {},
"n_memory_holes": 0,
Expand Down

0 comments on commit 3524621

Please sign in to comment.