Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit b0c3535

Browse files
authored
Update get_block_hash syscall implementation (#688)
* Update bounds and add FailureReason * Fetch hash from storage * Fix clippy * Update cairo dependencies * Updated contract_a * Revert update * Remove allow unused * Revert contract_a
1 parent 4e91c80 commit b0c3535

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

src/definitions/constants.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,6 @@ lazy_static! {
9191

9292
pub static ref VALIDATE_ENTRY_POINT_SELECTOR: Felt252 =
9393
felt_str!("626969833899987279399947180575486623810258720106406659648356883742278317941");
94+
95+
pub static ref BLOCK_HASH_CONTRACT_ADDRESS: Address = Address(1.into());
9496
}

src/syscalls/business_logic_syscall_handler.rs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![allow(dead_code)] // TODO: Remove this!
1+
#![allow(clippy::absurd_extreme_comparisons)]
22

33
use std::collections::HashMap;
44
use std::ops::Add;
@@ -20,6 +20,7 @@ use super::{
2020
syscall_response::{CallContractResponse, FailureReason, ResponseBody},
2121
};
2222
use crate::definitions::block_context::BlockContext;
23+
use crate::definitions::constants::BLOCK_HASH_CONTRACT_ADDRESS;
2324
use crate::services::api::contract_classes::compiled_class::CompiledClass;
2425
use crate::state::BlockInfo;
2526
use crate::transaction::error::TransactionError;
@@ -435,33 +436,52 @@ impl<'a, T: State + StateReader> BusinessLogicSyscallHandler<'a, T> {
435436
SyscallRequest::GetBlockTimestamp(req) => {
436437
self.get_block_timestamp(vm, req, remaining_gas)
437438
}
438-
SyscallRequest::GetBlockHash(req) => Ok(self.get_block_hash(req, remaining_gas)),
439+
SyscallRequest::GetBlockHash(req) => self.get_block_hash(vm, req, remaining_gas),
439440
SyscallRequest::ReplaceClass(req) => self.replace_class(vm, req, remaining_gas),
440441
}
441442
}
442443

443-
fn get_block_hash(&self, request: GetBlockHashRequest, remaining_gas: u128) -> SyscallResponse {
444+
fn get_block_hash(
445+
&mut self,
446+
vm: &mut VirtualMachine,
447+
request: GetBlockHashRequest,
448+
remaining_gas: u128,
449+
) -> Result<SyscallResponse, SyscallHandlerError> {
444450
let block_number = request.block_number;
445451
let current_block_number = self.block_context.block_info.block_number;
446-
let block_hash = if block_number < current_block_number - 1024
447-
|| block_number > current_block_number - 10
448-
{
452+
453+
if block_number > current_block_number - 10 {
454+
let out_of_range_felt = Felt252::from_bytes_be("Block number out of range".as_bytes());
455+
let retdata_start =
456+
self.allocate_segment(vm, vec![MaybeRelocatable::from(out_of_range_felt)])?;
457+
let failure = FailureReason {
458+
retdata_start,
459+
retdata_end: (retdata_start + 1)?,
460+
};
461+
462+
return Ok(SyscallResponse {
463+
gas: remaining_gas,
464+
body: Some(ResponseBody::Failure(failure)),
465+
});
466+
}
467+
468+
// FIXME: Update this after release.
469+
const V_0_12_0_FIRST_BLOCK: u64 = 0;
470+
let block_hash = if block_number < V_0_12_0_FIRST_BLOCK {
449471
Felt252::zero()
450472
} else {
451-
// Fetch hash from block header
452-
self.block_context
453-
.blocks()
454-
.get(&block_number)
455-
.map(|block| Felt252::from_bytes_be(block.header.block_hash.0.bytes()))
456-
.unwrap_or_default()
473+
self.starknet_storage_state.state.get_storage_at(&(
474+
BLOCK_HASH_CONTRACT_ADDRESS.clone(),
475+
Felt252::new(block_number).to_be_bytes(),
476+
))?
457477
};
458478

459-
SyscallResponse {
479+
Ok(SyscallResponse {
460480
gas: remaining_gas,
461481
body: Some(ResponseBody::GetBlockHash(GetBlockHashResponse {
462482
block_hash,
463483
})),
464-
}
484+
})
465485
}
466486

467487
pub(crate) fn post_run(

0 commit comments

Comments
 (0)