From b4be593f792b8d81a79c8561efc14276fa40fbe7 Mon Sep 17 00:00:00 2001 From: Noam Spiegelstein Date: Wed, 25 Dec 2024 15:31:21 +0200 Subject: [PATCH] feat(starknet_state_sync): implement state sync get latest block number --- .../starknet_gateway/src/rpc_state_reader.rs | 4 +-- crates/starknet_gateway/src/state_reader.rs | 2 +- .../src/state_reader_test_utils.rs | 4 +-- .../src/stateful_transaction_validator.rs | 5 +++- .../starknet_gateway/src/sync_state_reader.rs | 12 ++++++--- crates/starknet_state_sync/src/lib.rs | 9 +++++++ .../src/communication.rs | 26 +++++++++++++++++++ 7 files changed, 53 insertions(+), 9 deletions(-) diff --git a/crates/starknet_gateway/src/rpc_state_reader.rs b/crates/starknet_gateway/src/rpc_state_reader.rs index e6abf8cd0a1..df46e4e0e5a 100644 --- a/crates/starknet_gateway/src/rpc_state_reader.rs +++ b/crates/starknet_gateway/src/rpc_state_reader.rs @@ -185,8 +185,8 @@ pub struct RpcStateReaderFactory { } impl StateReaderFactory for RpcStateReaderFactory { - fn get_state_reader_from_latest_block(&self) -> Box { - Box::new(RpcStateReader::from_latest(&self.config)) + fn get_state_reader_from_latest_block(&self) -> StateResult> { + Ok(Box::new(RpcStateReader::from_latest(&self.config))) } fn get_state_reader(&self, block_number: BlockNumber) -> Box { diff --git a/crates/starknet_gateway/src/state_reader.rs b/crates/starknet_gateway/src/state_reader.rs index b026bbe6ef0..b65c9522d9a 100644 --- a/crates/starknet_gateway/src/state_reader.rs +++ b/crates/starknet_gateway/src/state_reader.rs @@ -14,7 +14,7 @@ pub trait MempoolStateReader: BlockifierStateReader + Send + Sync { #[cfg_attr(test, automock)] pub trait StateReaderFactory: Send + Sync { - fn get_state_reader_from_latest_block(&self) -> Box; + fn get_state_reader_from_latest_block(&self) -> StateResult>; fn get_state_reader(&self, block_number: BlockNumber) -> Box; } diff --git a/crates/starknet_gateway/src/state_reader_test_utils.rs b/crates/starknet_gateway/src/state_reader_test_utils.rs index 80c8fc8b516..addf37793b1 100644 --- a/crates/starknet_gateway/src/state_reader_test_utils.rs +++ b/crates/starknet_gateway/src/state_reader_test_utils.rs @@ -57,8 +57,8 @@ pub struct TestStateReaderFactory { } impl StateReaderFactory for TestStateReaderFactory { - fn get_state_reader_from_latest_block(&self) -> Box { - Box::new(self.state_reader.clone()) + fn get_state_reader_from_latest_block(&self) -> StateResult> { + Ok(Box::new(self.state_reader.clone())) } fn get_state_reader(&self, _block_number: BlockNumber) -> Box { diff --git a/crates/starknet_gateway/src/stateful_transaction_validator.rs b/crates/starknet_gateway/src/stateful_transaction_validator.rs index fd04f6d66fd..b8ac9b42fb2 100644 --- a/crates/starknet_gateway/src/stateful_transaction_validator.rs +++ b/crates/starknet_gateway/src/stateful_transaction_validator.rs @@ -133,7 +133,10 @@ fn skip_stateful_validations(tx: &ExecutableTransaction, account_nonce: Nonce) - pub fn get_latest_block_info( state_reader_factory: &dyn StateReaderFactory, ) -> StatefulTransactionValidatorResult { - 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() } diff --git a/crates/starknet_gateway/src/sync_state_reader.rs b/crates/starknet_gateway/src/sync_state_reader.rs index 8fbd809d06a..6c92684ebf6 100644 --- a/crates/starknet_gateway/src/sync_state_reader.rs +++ b/crates/starknet_gateway/src/sync_state_reader.rs @@ -115,9 +115,15 @@ pub struct SyncStateReaderFactory { } impl StateReaderFactory for SyncStateReaderFactory { - // TODO(noamsp): Decide if we need this - fn get_state_reader_from_latest_block(&self) -> Box { - todo!() + fn get_state_reader_from_latest_block(&self) -> StateResult> { + let latest_block_number = block_on(self.shared_state_sync_client.get_latest_block_number()) + .map_err(|e| StateError::StateReadError(e.to_string()))? + .ok_or(StateError::StateReadError("Block not found, Empty state diff".to_string()))?; + + Ok(Box::new(SyncStateReader::from_number( + self.shared_state_sync_client.clone(), + latest_block_number, + ))) } fn get_state_reader(&self, block_number: BlockNumber) -> Box { diff --git a/crates/starknet_state_sync/src/lib.rs b/crates/starknet_state_sync/src/lib.rs index 084bffbf310..a87a323519d 100644 --- a/crates/starknet_state_sync/src/lib.rs +++ b/crates/starknet_state_sync/src/lib.rs @@ -74,6 +74,9 @@ impl ComponentRequestHandler for StateSync self.get_compiled_class_deprecated(block_number, class_hash), ) } + StateSyncRequest::GetLatestBlockNumber() => { + StateSyncResponse::GetLatestBlockNumber(self.get_latest_block_number()) + } } } } @@ -184,6 +187,12 @@ impl StateSync { .ok_or(StateSyncError::ClassNotFound(class_hash))?; Ok(ContractClass::V0(deprecated_compiled_contract_class)) } + + fn get_latest_block_number(&self) -> StateSyncResult> { + 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( diff --git a/crates/starknet_state_sync_types/src/communication.rs b/crates/starknet_state_sync_types/src/communication.rs index 013d5d26479..0a1e5478638 100644 --- a/crates/starknet_state_sync_types/src/communication.rs +++ b/crates/starknet_state_sync_types/src/communication.rs @@ -68,6 +68,8 @@ pub trait StateSyncClient: Send + Sync { class_hash: ClassHash, ) -> StateSyncClientResult; + async fn get_latest_block_number(&self) -> StateSyncClientResult>; + // TODO: Add get_compiled_class_hash for StateSyncReader } @@ -95,6 +97,7 @@ pub enum StateSyncRequest { GetNonceAt(BlockNumber, ContractAddress), GetClassHashAt(BlockNumber, ContractAddress), GetCompiledClassDeprecated(BlockNumber, ClassHash), + GetLatestBlockNumber(), } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -106,6 +109,7 @@ pub enum StateSyncResponse { GetNonceAt(StateSyncResult), GetClassHashAt(StateSyncResult), GetCompiledClassDeprecated(StateSyncResult), + GetLatestBlockNumber(StateSyncResult>), } #[async_trait] @@ -194,6 +198,17 @@ impl StateSyncClient for LocalStateSyncClient { StateSyncError ) } + + async fn get_latest_block_number(&self) -> StateSyncClientResult> { + let request = StateSyncRequest::GetLatestBlockNumber(); + let response = self.send(request).await; + handle_response_variants!( + StateSyncResponse, + GetLatestBlockNumber, + StateSyncClientError, + StateSyncError + ) + } } #[async_trait] @@ -282,4 +297,15 @@ impl StateSyncClient for RemoteStateSyncClient { StateSyncError ) } + + async fn get_latest_block_number(&self) -> StateSyncClientResult> { + let request = StateSyncRequest::GetLatestBlockNumber(); + let response = self.send(request).await; + handle_response_variants!( + StateSyncResponse, + GetLatestBlockNumber, + StateSyncClientError, + StateSyncError + ) + } }