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(starknet_state_sync): implement state sync get latest block number #2944

Merged
merged 1 commit into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 5 additions & 2 deletions crates/starknet_gateway/src/rpc_state_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use starknet_api::block::{BlockInfo, BlockNumber};
use starknet_api::contract_class::SierraVersion;
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::state::StorageKey;
use starknet_state_sync_types::communication::StateSyncClientResult;
use starknet_types_core::felt::Felt;

use crate::config::RpcStateReaderConfig;
Expand Down Expand Up @@ -185,8 +186,10 @@ pub struct RpcStateReaderFactory {
}

impl StateReaderFactory for RpcStateReaderFactory {
fn get_state_reader_from_latest_block(&self) -> Box<dyn MempoolStateReader> {
Box::new(RpcStateReader::from_latest(&self.config))
fn get_state_reader_from_latest_block(
&self,
) -> StateSyncClientResult<Box<dyn MempoolStateReader>> {
Ok(Box::new(RpcStateReader::from_latest(&self.config)))
}

fn get_state_reader(&self, block_number: BlockNumber) -> Box<dyn MempoolStateReader> {
Expand Down
5 changes: 4 additions & 1 deletion crates/starknet_gateway/src/state_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use mockall::automock;
use starknet_api::block::{BlockInfo, BlockNumber};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::state::StorageKey;
use starknet_state_sync_types::communication::StateSyncClientResult;
use starknet_types_core::felt::Felt;

pub trait MempoolStateReader: BlockifierStateReader + Send + Sync {
Expand All @@ -14,7 +15,9 @@ pub trait MempoolStateReader: BlockifierStateReader + Send + Sync {

#[cfg_attr(test, automock)]
pub trait StateReaderFactory: Send + Sync {
fn get_state_reader_from_latest_block(&self) -> Box<dyn MempoolStateReader>;
fn get_state_reader_from_latest_block(
&self,
) -> StateSyncClientResult<Box<dyn MempoolStateReader>>;
fn get_state_reader(&self, block_number: BlockNumber) -> Box<dyn MempoolStateReader>;
}

Expand Down
7 changes: 5 additions & 2 deletions crates/starknet_gateway/src/state_reader_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use starknet_api::block::{BlockInfo, BlockNumber};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::state::StorageKey;
use starknet_api::transaction::fields::Fee;
use starknet_state_sync_types::communication::StateSyncClientResult;
use starknet_types_core::felt::Felt;

use crate::state_reader::{MempoolStateReader, StateReaderFactory};
Expand Down Expand Up @@ -57,8 +58,10 @@ pub struct TestStateReaderFactory {
}

impl StateReaderFactory for TestStateReaderFactory {
fn get_state_reader_from_latest_block(&self) -> Box<dyn MempoolStateReader> {
Box::new(self.state_reader.clone())
fn get_state_reader_from_latest_block(
&self,
) -> StateSyncClientResult<Box<dyn MempoolStateReader>> {
Ok(Box::new(self.state_reader.clone()))
}

fn get_state_reader(&self, _block_number: BlockNumber) -> Box<dyn MempoolStateReader> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ fn skip_stateful_validations(tx: &ExecutableTransaction, account_nonce: Nonce) -
pub fn get_latest_block_info(
state_reader_factory: &dyn StateReaderFactory,
) -> StatefulTransactionValidatorResult<BlockInfo> {
let state_reader = state_reader_factory.get_state_reader_from_latest_block();
let state_reader = state_reader_factory.get_state_reader_from_latest_block().map_err(|e| {
error!("Failed to get state reader from latest block: {}", e);
GatewaySpecError::UnexpectedError { data: "Internal server error.".to_owned() }
})?;
state_reader.get_block_info().map_err(|e| {
error!("Failed to get latest block info: {}", e);
GatewaySpecError::UnexpectedError { data: "Internal server error.".to_owned() }
Expand Down
21 changes: 17 additions & 4 deletions crates/starknet_gateway/src/sync_state_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ use starknet_api::contract_class::ContractClass;
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::data_availability::L1DataAvailabilityMode;
use starknet_api::state::StorageKey;
use starknet_state_sync_types::communication::SharedStateSyncClient;
use starknet_state_sync_types::communication::{
SharedStateSyncClient,
StateSyncClientError,
StateSyncClientResult,
};
use starknet_state_sync_types::errors::StateSyncError;
use starknet_types_core::felt::Felt;

use crate::state_reader::{MempoolStateReader, StateReaderFactory};
Expand Down Expand Up @@ -118,9 +123,17 @@ pub struct SyncStateReaderFactory {
}

impl StateReaderFactory for SyncStateReaderFactory {
// TODO(noamsp): Decide if we need this
fn get_state_reader_from_latest_block(&self) -> Box<dyn MempoolStateReader> {
todo!()
fn get_state_reader_from_latest_block(
&self,
) -> StateSyncClientResult<Box<dyn MempoolStateReader>> {
let latest_block_number =
block_on(self.shared_state_sync_client.get_latest_block_number())?
.ok_or(StateSyncClientError::StateSyncError(StateSyncError::EmptyState))?;

Ok(Box::new(SyncStateReader::from_number(
self.shared_state_sync_client.clone(),
latest_block_number,
)))
}

fn get_state_reader(&self, block_number: BlockNumber) -> Box<dyn MempoolStateReader> {
Expand Down
9 changes: 9 additions & 0 deletions crates/starknet_state_sync/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ impl ComponentRequestHandler<StateSyncRequest, StateSyncResponse> for StateSync
self.get_compiled_class_deprecated(block_number, class_hash),
)
}
StateSyncRequest::GetLatestBlockNumber() => {
StateSyncResponse::GetLatestBlockNumber(self.get_latest_block_number())
}
}
}
}
Expand Down Expand Up @@ -190,6 +193,12 @@ impl StateSync {
.ok_or(StateSyncError::ClassNotFound(class_hash))?;
Ok(ContractClass::V0(deprecated_compiled_contract_class))
}

fn get_latest_block_number(&self) -> StateSyncResult<Option<BlockNumber>> {
let txn = self.storage_reader.begin_ro_txn()?;
let latest_block_number = txn.get_state_marker()?.prev();
Ok(latest_block_number)
}
}

fn verify_synced_up_to<Mode: TransactionKind>(
Expand Down
26 changes: 26 additions & 0 deletions crates/starknet_state_sync_types/src/communication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ pub trait StateSyncClient: Send + Sync {
class_hash: ClassHash,
) -> StateSyncClientResult<ContractClass>;

async fn get_latest_block_number(&self) -> StateSyncClientResult<Option<BlockNumber>>;

// TODO: Add get_compiled_class_hash for StateSyncReader
}

Expand Down Expand Up @@ -95,6 +97,7 @@ pub enum StateSyncRequest {
GetNonceAt(BlockNumber, ContractAddress),
GetClassHashAt(BlockNumber, ContractAddress),
GetCompiledClassDeprecated(BlockNumber, ClassHash),
GetLatestBlockNumber(),
}

#[derive(Clone, Debug, Serialize, Deserialize)]
Expand All @@ -106,6 +109,7 @@ pub enum StateSyncResponse {
GetNonceAt(StateSyncResult<Nonce>),
GetClassHashAt(StateSyncResult<ClassHash>),
GetCompiledClassDeprecated(StateSyncResult<ContractClass>),
GetLatestBlockNumber(StateSyncResult<Option<BlockNumber>>),
}

#[async_trait]
Expand Down Expand Up @@ -194,6 +198,17 @@ impl StateSyncClient for LocalStateSyncClient {
StateSyncError
)
}

async fn get_latest_block_number(&self) -> StateSyncClientResult<Option<BlockNumber>> {
let request = StateSyncRequest::GetLatestBlockNumber();
let response = self.send(request).await;
handle_response_variants!(
StateSyncResponse,
GetLatestBlockNumber,
StateSyncClientError,
StateSyncError
)
}
}

#[async_trait]
Expand Down Expand Up @@ -282,4 +297,15 @@ impl StateSyncClient for RemoteStateSyncClient {
StateSyncError
)
}

async fn get_latest_block_number(&self) -> StateSyncClientResult<Option<BlockNumber>> {
let request = StateSyncRequest::GetLatestBlockNumber();
let response = self.send(request).await;
handle_response_variants!(
StateSyncResponse,
GetLatestBlockNumber,
StateSyncClientError,
StateSyncError
)
}
}
2 changes: 2 additions & 0 deletions crates/starknet_state_sync_types/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub enum StateSyncError {
SendError(String),
#[error("Unexpected starknet api error: {0}")]
StarknetApiError(String),
#[error("State is empty, latest block returned None")]
EmptyState,
}

impl From<StorageError> for StateSyncError {
Expand Down
Loading