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 11, 2023
1 parent a30aa9e commit 8019cc6
Show file tree
Hide file tree
Showing 9 changed files with 2,333 additions and 1,665 deletions.

Large diffs are not rendered by default.

3,015 changes: 1,564 additions & 1,451 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,11 @@ mod TestContract {
starknet::syscalls::emit_event_syscall(keys.span(), data.span()).unwrap_syscall();
}

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

#[starknet::external]
fn test_get_execution_info(
self: @Storage,
Expand Down
6 changes: 6 additions & 0 deletions crates/blockifier/src/abi/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,15 @@ pub const TRANSACTION_GAS_COST: u64 =
pub const CALL_CONTRACT_GAS_COST: u64 = 10 * STEP_GAS_COST + ENTRY_POINT_GAS_COST;
pub const DEPLOY_GAS_COST: u64 = 200 * STEP_GAS_COST + ENTRY_POINT_GAS_COST;
pub const EMIT_EVENT_GAS_COST: u64 = 10 * STEP_GAS_COST;
pub const GET_BLOCK_HASH_GAS_COST: u64 = 50 * STEP_GAS_COST;
pub const GET_EXECUTION_INFO_GAS_COST: u64 = 10 * STEP_GAS_COST;
pub const LIBRARY_CALL_GAS_COST: u64 = CALL_CONTRACT_GAS_COST;
pub const REPLACE_CLASS_GAS_COST: u64 = 50 * STEP_GAS_COST;
pub const SEND_MESSAGE_TO_L1_GAS_COST: u64 = 50 * STEP_GAS_COST;
pub const STORAGE_READ_GAS_COST: u64 = 50 * STEP_GAS_COST;
pub const STORAGE_WRITE_GAS_COST: u64 = 50 * STEP_GAS_COST;

// OS reserved contract addresses.

// This contract stores the block number -> block hash mapping.
pub const BLOCK_HASH_CONTRACT_ADDRESS: u64 = 1;
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 @@ -42,6 +42,7 @@ pub enum DeprecatedSyscallSelector {
DelegateL1Handler,
Deploy,
EmitEvent,
GetBlockHash,
GetBlockNumber,
GetBlockTimestamp,
GetCallerAddress,
Expand Down Expand Up @@ -71,6 +72,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
11 changes: 7 additions & 4 deletions crates/blockifier/src/execution/syscalls/hint_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,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 @@ -185,6 +185,9 @@ impl<'a> SyscallHintProcessor<'a> {
SyscallSelector::EmitEvent => {
self.execute_syscall(vm, emit_event, constants::EMIT_EVENT_GAS_COST)
}
SyscallSelector::GetBlockHash => {
self.execute_syscall(vm, get_block_hash, constants::GET_BLOCK_HASH_GAS_COST)
}
SyscallSelector::GetExecutionInfo => {
self.execute_syscall(vm, get_execution_info, constants::GET_EXECUTION_INFO_GAS_COST)
}
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 @@ -283,6 +283,53 @@ pub fn emit_event(
Ok(EmitEventResponse {})
}

// GetBlockHash syscall.

#[derive(Debug, Eq, PartialEq)]

// TODO(Arni, 8/6/2023): Consider replacing with block_number: u64 or with BlockNumber.
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_hash - block_number < 10.
// Returns the expected block hash if 10 <= latest_block_hash - 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<'_>,
_remaining_gas: &mut Felt252,
) -> SyscallResult<GetBlockHashResponse> {
let key = StorageKey::try_from(request.block_number)?;
let block_hash_contract_address =
ContractAddress::try_from(StarkFelt::from(constants::BLOCK_HASH_CONTRACT_ADDRESS))?;
let block_hash = syscall_handler.state.get_storage_at(block_hash_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 @@ -103,6 +103,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 8019cc6

Please sign in to comment.