Skip to content

Commit

Permalink
feat(starknet_state_sync): implement sync state reader get storage at
Browse files Browse the repository at this point in the history
  • Loading branch information
noamsp-starkware committed Dec 18, 2024
1 parent 0f4bcbd commit 528afd4
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/blockifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ stacker = { workspace = true, optional = true }
starknet-types-core.workspace = true
starknet_api.workspace = true
starknet_sierra_compile = { workspace = true, optional = true }
starknet_state_sync_types.workspace = true
strum.workspace = true
strum_macros.workspace = true
tempfile.workspace = true
Expand Down
3 changes: 3 additions & 0 deletions crates/blockifier/src/state/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use num_bigint::{BigUint, TryFromBigIntError};
use starknet_api::core::{ClassHash, ContractAddress};
use starknet_api::state::SierraContractClass;
use starknet_api::StarknetApiError;
use starknet_state_sync_types::communication::StateSyncClientError;
use thiserror::Error;

use crate::abi::constants;
Expand Down Expand Up @@ -32,6 +33,8 @@ pub enum StateError {
/// Represents all unexpected errors that may occur while reading from state.
#[error("Failed to read from state: {0}.")]
StateReadError(String),
#[error(transparent)]
StateSyncClientError(#[from] StateSyncClientError),
}

/// Ensures that the CASM and Sierra classes are coupled - Meaning that they both exist or are
Expand Down
1 change: 1 addition & 0 deletions crates/starknet_gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ async-trait.workspace = true
axum.workspace = true
blockifier = { workspace = true, features = ["testing"] }
cairo-lang-starknet-classes.workspace = true
futures.workspace = true
mempool_test_utils.workspace = true
papyrus_config.workspace = true
papyrus_network_types.workspace = true
Expand Down
13 changes: 10 additions & 3 deletions crates/starknet_gateway/src/sync_state_reader.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use blockifier::execution::contract_class::RunnableCompiledClass;
use blockifier::state::state_api::{StateReader as BlockifierStateReader, StateResult};
use futures::executor::block_on;
use starknet_api::block::{BlockInfo, BlockNumber};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::state::StorageKey;
Expand Down Expand Up @@ -32,10 +33,16 @@ impl MempoolStateReader for SyncStateReader {
impl BlockifierStateReader for SyncStateReader {
fn get_storage_at(
&self,
_contract_address: ContractAddress,
_key: StorageKey,
contract_address: ContractAddress,
key: StorageKey,
) -> StateResult<Felt> {
todo!()
let res = block_on(self.shared_state_sync_client.get_storage_at(
self.block_number,
contract_address,
key,
))?;

Ok(res.unwrap_or_default())
}

fn get_nonce_at(&self, _contract_address: ContractAddress) -> StateResult<Nonce> {
Expand Down
1 change: 1 addition & 0 deletions crates/starknet_state_sync/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ papyrus_network.workspace = true
papyrus_p2p_sync.workspace = true
papyrus_storage.workspace = true
serde.workspace = true
starknet-types-core.workspace = true
starknet_api = { workspace = true, features = ["testing"] }
starknet_sequencer_infra.workspace = true
starknet_state_sync_types.workspace = true
Expand Down
39 changes: 39 additions & 0 deletions crates/starknet_state_sync/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ use papyrus_storage::body::BodyStorageReader;
use papyrus_storage::state::StateStorageReader;
use papyrus_storage::StorageReader;
use starknet_api::block::BlockNumber;
use starknet_api::core::{ContractAddress, BLOCK_HASH_TABLE_ADDRESS};
use starknet_api::state::{StateNumber, StorageKey};
use starknet_sequencer_infra::component_definitions::{ComponentRequestHandler, ComponentStarter};
use starknet_sequencer_infra::component_server::{LocalComponentServer, RemoteComponentServer};
use starknet_state_sync_types::communication::{
StateSyncRequest,
StateSyncResponse,
StateSyncResult,
};
use starknet_state_sync_types::errors::StateSyncError;
use starknet_state_sync_types::state_sync_types::SyncBlock;
use starknet_types_core::felt::Felt;

use crate::config::StateSyncConfig;
use crate::runner::StateSyncRunner;
Expand All @@ -39,6 +43,13 @@ impl ComponentRequestHandler<StateSyncRequest, StateSyncResponse> for StateSync
StateSyncRequest::AddNewBlock(_block_number, _sync_block) => {
todo!()
}
StateSyncRequest::GetStorageAt(block_number, contract_address, storage_key) => {
StateSyncResponse::GetStorageAt(self.get_storage_at(
block_number,
contract_address,
storage_key,
))
}
}
}
}
Expand All @@ -58,6 +69,34 @@ impl StateSync {

Ok(None)
}

fn get_storage_at(
&self,
block_number: BlockNumber,
contract_address: ContractAddress,
storage_key: StorageKey,
) -> StateSyncResult<Option<Felt>> {
let txn = self.storage_reader.begin_ro_txn()?;

if let Some(state_number) = StateNumber::right_after_block(block_number) {
let state_reader = txn.get_state_reader()?;
let res = state_reader.get_storage_at(state_number, &contract_address, &storage_key)?;

// If the contract is not deployed, res will be 0. Checking if that's the case so
// that we'll return an error instead.
// Contract address 0x1 is a special address, it stores the block
// hashes. Contracts are not deployed to this address.
if res == Felt::default() && contract_address != BLOCK_HASH_TABLE_ADDRESS {
// check if the contract exists
state_reader.get_class_hash_at(state_number, &contract_address)?.ok_or_else(
|| StateSyncError::StorageError("Contract not found".to_string()),
)?;
}
return Ok(Some(res));
}

Ok(None)
}
}

pub type LocalStateSyncServer =
Expand Down
1 change: 1 addition & 0 deletions crates/starknet_state_sync_types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ async-trait.workspace = true
papyrus_proc_macros.workspace = true
papyrus_storage.workspace = true
serde = { workspace = true, features = ["derive"] }
starknet-types-core.workspace = true
starknet_api.workspace = true
starknet_sequencer_infra.workspace = true
thiserror.workspace = true
45 changes: 44 additions & 1 deletion crates/starknet_state_sync_types/src/communication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use async_trait::async_trait;
use papyrus_proc_macros::handle_response_variants;
use serde::{Deserialize, Serialize};
use starknet_api::block::BlockNumber;
use starknet_api::core::ContractAddress;
use starknet_api::state::StorageKey;
use starknet_sequencer_infra::component_client::{
ClientError,
LocalComponentClient,
Expand All @@ -13,6 +15,7 @@ use starknet_sequencer_infra::component_definitions::{
ComponentClient,
ComponentRequestAndResponseSender,
};
use starknet_types_core::felt::Felt;
use thiserror::Error;

use crate::errors::StateSyncError;
Expand All @@ -34,7 +37,13 @@ pub trait StateSyncClient: Send + Sync {
sync_block: SyncBlock,
) -> StateSyncClientResult<()>;

// TODO: add get_storage_at for BlockifierStateReader trait
async fn get_storage_at(
&self,
block_number: BlockNumber,
contract_address: ContractAddress,
storage_key: StorageKey,
) -> StateSyncClientResult<Option<Felt>>;

// TODO: add get_nonce_at for BlockifierStateReader trait
// TODO: add get_compiled_class for BlockifierStateReader trait
// TODO: add get_class_hash_at for BlockifierStateReader trait
Expand Down Expand Up @@ -63,12 +72,14 @@ pub type StateSyncRequestAndResponseSender =
pub enum StateSyncRequest {
GetBlock(BlockNumber),
AddNewBlock(BlockNumber, SyncBlock),
GetStorageAt(BlockNumber, ContractAddress, StorageKey),
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum StateSyncResponse {
GetBlock(StateSyncResult<Option<SyncBlock>>),
AddNewBlock(StateSyncResult<()>),
GetStorageAt(StateSyncResult<Option<Felt>>),
}

#[async_trait]
Expand Down Expand Up @@ -96,6 +107,22 @@ impl StateSyncClient for LocalStateSyncClient {
StateSyncError
)
}

async fn get_storage_at(
&self,
block_number: BlockNumber,
contract_address: ContractAddress,
storage_key: StorageKey,
) -> StateSyncClientResult<Option<Felt>> {
let request = StateSyncRequest::GetStorageAt(block_number, contract_address, storage_key);
let response = self.send(request).await;
handle_response_variants!(
StateSyncResponse,
GetStorageAt,
StateSyncClientError,
StateSyncError
)
}
}

#[async_trait]
Expand Down Expand Up @@ -123,4 +150,20 @@ impl StateSyncClient for RemoteStateSyncClient {
StateSyncError
)
}

async fn get_storage_at(
&self,
block_number: BlockNumber,
contract_address: ContractAddress,
storage_key: StorageKey,
) -> StateSyncClientResult<Option<Felt>> {
let request = StateSyncRequest::GetStorageAt(block_number, contract_address, storage_key);
let response = self.send(request).await;
handle_response_variants!(
StateSyncResponse,
GetStorageAt,
StateSyncClientError,
StateSyncError
)
}
}

0 comments on commit 528afd4

Please sign in to comment.