From b5f9e764f1bc6e802afa769794996ce5a8e03d47 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 e6abf8cd0a..df46e4e0e5 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 b026bbe6ef..b65c9522d9 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 80c8fc8b51..addf37793b 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 b08e6cf0f3..00c4d3c1e4 100644 --- a/crates/starknet_gateway/src/stateful_transaction_validator.rs +++ b/crates/starknet_gateway/src/stateful_transaction_validator.rs @@ -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 { - 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 0260f23d25..f5053aaeba 100644 --- a/crates/starknet_gateway/src/sync_state_reader.rs +++ b/crates/starknet_gateway/src/sync_state_reader.rs @@ -118,9 +118,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 8337e3514d..a9c50d1e18 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()) + } } } } @@ -188,6 +191,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 013d5d2647..0a1e547863 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 + ) + } }