From f339fbb89ad7a7b27ef283b62cd984c5c77d8825 Mon Sep 17 00:00:00 2001 From: Noam Spiegelstein Date: Sun, 22 Dec 2024 17:53:59 +0200 Subject: [PATCH] feat(starknet_state_sync): implement sync state reader get block info --- Cargo.lock | 1 + .../starknet_gateway/src/sync_state_reader.rs | 10 ++++- crates/starknet_state_sync/Cargo.toml | 1 + crates/starknet_state_sync/src/lib.rs | 42 ++++++++++++++++++- .../src/communication.rs | 37 +++++++++++++++- 5 files changed, 87 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7f15bb5903..c536946db2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10779,6 +10779,7 @@ name = "starknet_state_sync" version = "0.0.0" dependencies = [ "async-trait", + "blockifier", "futures", "papyrus_config", "papyrus_network", diff --git a/crates/starknet_gateway/src/sync_state_reader.rs b/crates/starknet_gateway/src/sync_state_reader.rs index 17c9dba820..d475d3d8e0 100644 --- a/crates/starknet_gateway/src/sync_state_reader.rs +++ b/crates/starknet_gateway/src/sync_state_reader.rs @@ -28,7 +28,15 @@ impl SyncStateReader { impl MempoolStateReader for SyncStateReader { fn get_block_info(&self) -> StateResult { - todo!() + let maybe_block_info = block_on(self.state_sync_client.get_block_info(self.block_number)) + .map_err(|e| StateError::StateReadError(e.to_string()))?; + + let block_info = match maybe_block_info { + Some(block_info) => block_info, + None => return Err(StateError::StateReadError("Block info not found".to_string())), + }; + + Ok(block_info) } } diff --git a/crates/starknet_state_sync/Cargo.toml b/crates/starknet_state_sync/Cargo.toml index 1691687717..b31122e53f 100644 --- a/crates/starknet_state_sync/Cargo.toml +++ b/crates/starknet_state_sync/Cargo.toml @@ -10,6 +10,7 @@ workspace = true [dependencies] async-trait.workspace = true +blockifier.workspace = true futures.workspace = true papyrus_config.workspace = true papyrus_network.workspace = true diff --git a/crates/starknet_state_sync/src/lib.rs b/crates/starknet_state_sync/src/lib.rs index 322e5cd70f..0f955cee24 100644 --- a/crates/starknet_state_sync/src/lib.rs +++ b/crates/starknet_state_sync/src/lib.rs @@ -2,17 +2,21 @@ pub mod config; pub mod runner; use async_trait::async_trait; +use blockifier::blockifier::block::validated_gas_prices; use futures::channel::mpsc::{channel, Sender}; use futures::SinkExt; use papyrus_storage::body::BodyStorageReader; use papyrus_storage::compiled_class::CasmStorageReader; use papyrus_storage::db::TransactionKind; +use papyrus_storage::header::HeaderStorageReader; use papyrus_storage::state::StateStorageReader; use papyrus_storage::{StorageReader, StorageTxn}; -use starknet_api::block::BlockNumber; +use starknet_api::block::{BlockInfo, BlockNumber, GasPrice, NonzeroGasPrice}; use starknet_api::contract_class::{ContractClass, SierraVersion}; use starknet_api::core::{ClassHash, ContractAddress, Nonce, BLOCK_HASH_TABLE_ADDRESS}; +use starknet_api::data_availability::L1DataAvailabilityMode; use starknet_api::state::{StateNumber, StorageKey}; +use starknet_api::StarknetApiResult; use starknet_sequencer_infra::component_definitions::{ComponentRequestHandler, ComponentStarter}; use starknet_sequencer_infra::component_server::{LocalComponentServer, RemoteComponentServer}; use starknet_state_sync_types::communication::{StateSyncRequest, StateSyncResponse}; @@ -73,6 +77,9 @@ impl ComponentRequestHandler for StateSync self.get_compiled_class_deprecated(block_number, class_hash), ) } + StateSyncRequest::GetBlockInfo(block_number) => { + StateSyncResponse::GetBlockInfo(self.get_block_info(block_number)) + } } } } @@ -192,6 +199,35 @@ impl StateSync { .ok_or(StateSyncError::ClassNotFound(class_hash))?; Ok(ContractClass::V0(deprecated_compiled_contract_class)) } + + fn get_block_info(&self, block_number: BlockNumber) -> StateSyncResult> { + let txn = self.storage_reader.begin_ro_txn()?; + + if let Some(block_header) = txn.get_block_header(block_number)? { + let block_header_without_hash = block_header.block_header_without_hash; + let block_info = BlockInfo { + block_number: block_header_without_hash.block_number, + sequencer_address: block_header_without_hash.sequencer.0, + block_timestamp: block_header_without_hash.timestamp, + gas_prices: validated_gas_prices( + parse_gas_price(block_header_without_hash.l1_gas_price.price_in_wei)?, + parse_gas_price(block_header_without_hash.l1_gas_price.price_in_fri)?, + parse_gas_price(block_header_without_hash.l1_data_gas_price.price_in_wei)?, + parse_gas_price(block_header_without_hash.l1_data_gas_price.price_in_fri)?, + parse_gas_price(block_header_without_hash.l2_gas_price.price_in_wei)?, + parse_gas_price(block_header_without_hash.l2_gas_price.price_in_fri)?, + ), + use_kzg_da: matches!( + block_header_without_hash.l1_da_mode, + L1DataAvailabilityMode::Blob + ), + }; + + return Ok(Some(block_info)); + } + + Ok(None) + } } fn verify_synced_up_to( @@ -207,6 +243,10 @@ fn verify_synced_up_to( Err(StateSyncError::BlockNotFound(block_number)) } +fn parse_gas_price(gas_price: GasPrice) -> StarknetApiResult { + NonzeroGasPrice::new(gas_price) +} + pub type LocalStateSyncServer = LocalComponentServer; pub type RemoteStateSyncServer = RemoteComponentServer; diff --git a/crates/starknet_state_sync_types/src/communication.rs b/crates/starknet_state_sync_types/src/communication.rs index 4c1a56c794..2af775b4e7 100644 --- a/crates/starknet_state_sync_types/src/communication.rs +++ b/crates/starknet_state_sync_types/src/communication.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use async_trait::async_trait; use papyrus_proc_macros::handle_response_variants; use serde::{Deserialize, Serialize}; -use starknet_api::block::BlockNumber; +use starknet_api::block::{BlockInfo, BlockNumber}; use starknet_api::contract_class::ContractClass; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; @@ -65,8 +65,12 @@ pub trait StateSyncClient: Send + Sync { class_hash: ClassHash, ) -> StateSyncClientResult; + async fn get_block_info( + &self, + block_number: BlockNumber, + ) -> StateSyncClientResult>; + // TODO: Add get_compiled_class_hash for StateSyncReader - // TODO: Add get_block_info for StateSyncReader } #[derive(Clone, Debug, Error)] @@ -92,6 +96,7 @@ pub enum StateSyncRequest { GetNonceAt(BlockNumber, ContractAddress), GetClassHashAt(BlockNumber, ContractAddress), GetCompiledClassDeprecated(BlockNumber, ClassHash), + GetBlockInfo(BlockNumber), } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -102,6 +107,7 @@ pub enum StateSyncResponse { GetNonceAt(StateSyncResult), GetClassHashAt(StateSyncResult), GetCompiledClassDeprecated(StateSyncResult), + GetBlockInfo(StateSyncResult>), } #[async_trait] @@ -190,6 +196,19 @@ impl StateSyncClient for LocalStateSyncClient { StateSyncError ) } + async fn get_block_info( + &self, + block_number: BlockNumber, + ) -> StateSyncClientResult> { + let request = StateSyncRequest::GetBlockInfo(block_number); + let response = self.send(request).await; + handle_response_variants!( + StateSyncResponse, + GetBlockInfo, + StateSyncClientError, + StateSyncError + ) + } } #[async_trait] @@ -278,4 +297,18 @@ impl StateSyncClient for RemoteStateSyncClient { StateSyncError ) } + + async fn get_block_info( + &self, + block_number: BlockNumber, + ) -> StateSyncClientResult> { + let request = StateSyncRequest::GetBlockInfo(block_number); + let response = self.send(request).await; + handle_response_variants!( + StateSyncResponse, + GetBlockInfo, + StateSyncClientError, + StateSyncError + ) + } }