diff --git a/CHANGELOG.md b/CHANGELOG.md index 682f64b0b..5fba2ffb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Next release +- fix(rpc): get_class - refactor: mapping db - perf(db): contract key history now using rocksdb iterators for history - fix(root): Cleaned state root commitments crate diff --git a/crates/client/db/src/storage_handler/primitives/contract_class.rs b/crates/client/db/src/storage_handler/primitives/contract_class.rs index ec802b896..4d35c8d68 100644 --- a/crates/client/db/src/storage_handler/primitives/contract_class.rs +++ b/crates/client/db/src/storage_handler/primitives/contract_class.rs @@ -28,6 +28,7 @@ pub struct StorageContractClassData { pub abi: ContractAbi, pub sierra_program_length: u64, pub abi_length: u64, + pub block_number: u64, } #[derive(Debug, Clone, Encode, Decode)] diff --git a/crates/client/db/src/storage_updates.rs b/crates/client/db/src/storage_updates.rs index 50c1160dd..a7dbf8930 100644 --- a/crates/client/db/src/storage_updates.rs +++ b/crates/client/db/src/storage_updates.rs @@ -105,7 +105,10 @@ pub async fn store_class_update(block_number: u64, class_update: ClassUpdateWrap contract_class_wrapper; handler_contract_class_data_mut - .insert(class_hash, StorageContractClassData { contract_class, abi, sierra_program_length, abi_length }) + .insert( + class_hash, + StorageContractClassData { contract_class, abi, sierra_program_length, abi_length, block_number }, + ) .unwrap(); }, ); diff --git a/crates/client/rpc/src/methods/read/get_class.rs b/crates/client/rpc/src/methods/read/get_class.rs index abbfd48b6..1dc9da785 100644 --- a/crates/client/rpc/src/methods/read/get_class.rs +++ b/crates/client/rpc/src/methods/read/get_class.rs @@ -5,6 +5,7 @@ use mp_felt::Felt252Wrapper; use starknet_core::types::{BlockId, ContractClass, FieldElement}; use crate::errors::StarknetRpcApiError; +use crate::methods::trace::utils::block_number_by_id; /// Get the contract class definition in the given block associated with the given hash. /// @@ -18,7 +19,7 @@ use crate::errors::StarknetRpcApiError; /// /// Returns the contract class definition if found. In case of an error, returns a /// `StarknetRpcApiError` indicating either `BlockNotFound` or `ClassHashNotFound`. -pub fn get_class(_block_id: BlockId, class_hash: FieldElement) -> RpcResult { +pub fn get_class(block_id: BlockId, class_hash: FieldElement) -> RpcResult { let class_hash = Felt252Wrapper(class_hash).into(); // TODO: get class for the given block when block_number will be stored in @@ -30,7 +31,16 @@ pub fn get_class(_block_id: BlockId, class_hash: FieldElement) -> RpcResult Err(StarknetRpcApiError::ClassHashNotFound.into()), Ok(Some(class)) => { - let StorageContractClassData { contract_class, abi, sierra_program_length, abi_length } = class; + let StorageContractClassData { + contract_class, + abi, + sierra_program_length, + abi_length, + block_number: declared_at_block, + } = class; + if declared_at_block >= block_number_by_id(block_id)? { + return Err(StarknetRpcApiError::ClassHashNotFound.into()); + } Ok(ContractClassWrapper { contract: contract_class, abi, sierra_program_length, abi_length } .try_into() .map_err(|e| { diff --git a/crates/client/rpc/src/methods/read/get_class_at.rs b/crates/client/rpc/src/methods/read/get_class_at.rs index b25779d01..394075788 100644 --- a/crates/client/rpc/src/methods/read/get_class_at.rs +++ b/crates/client/rpc/src/methods/read/get_class_at.rs @@ -49,7 +49,8 @@ pub fn get_class_at(block_id: BlockId, contract_address: FieldElement) -> RpcRes }; // converting from stored Blockifier class to rpc class - let StorageContractClassData { contract_class, abi, sierra_program_length, abi_length } = contract_class_data; + let StorageContractClassData { contract_class, abi, sierra_program_length, abi_length, block_number: _ } = + contract_class_data; Ok(ContractClassWrapper { contract: contract_class, abi, sierra_program_length, abi_length }.try_into().map_err( |e| { log::error!("Failed to convert contract class from hash '{class_hash}' to RPC contract class: {e}");