diff --git a/crates/papyrus_rpc/src/v0_7/api/api_impl.rs b/crates/papyrus_rpc/src/v0_7/api/api_impl.rs index c094e92b5a..27f2127ba7 100644 --- a/crates/papyrus_rpc/src/v0_7/api/api_impl.rs +++ b/crates/papyrus_rpc/src/v0_7/api/api_impl.rs @@ -1,7 +1,6 @@ use std::sync::Arc; use async_trait::async_trait; -use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use jsonrpsee::core::RpcResult; use jsonrpsee::types::ErrorObjectOwned; use jsonrpsee::RpcModule; @@ -117,6 +116,7 @@ use super::{ BlockHashAndNumber, BlockId, CallRequest, + CompiledContractClass, ContinuationToken, EventFilter, EventsChunk, @@ -1437,7 +1437,7 @@ impl JsonRpcServer for JsonRpcServerImpl { &self, block_id: BlockId, class_hash: ClassHash, - ) -> RpcResult { + ) -> RpcResult { let storage_txn = self.storage_reader.begin_ro_txn().map_err(internal_server_error)?; let block_number = get_accepted_block_number(&storage_txn, block_id)?; let class_definition_block_number = storage_txn @@ -1449,11 +1449,20 @@ impl JsonRpcServer for JsonRpcServerImpl { if class_definition_block_number > block_number { return Err(ErrorObjectOwned::from(CLASS_HASH_NOT_FOUND)); } - let casm = storage_txn - .get_casm(&class_hash) + + if let Some(casm) = storage_txn.get_casm(&class_hash).map_err(internal_server_error)? { + return Ok(CompiledContractClass::V1(casm)); + } + + let state_number = StateNumber::right_after_block(block_number) + .ok_or_else(|| ErrorObjectOwned::from(CLASS_HASH_NOT_FOUND))?; + let deprecated_compiled_contract_class = storage_txn + .get_state_reader() + .map_err(internal_server_error)? + .get_deprecated_class_definition_at(state_number, &class_hash) .map_err(internal_server_error)? .ok_or_else(|| ErrorObjectOwned::from(CLASS_HASH_NOT_FOUND))?; - Ok(casm) + Ok(CompiledContractClass::V0(deprecated_compiled_contract_class)) } } diff --git a/crates/papyrus_rpc/src/v0_7/api/mod.rs b/crates/papyrus_rpc/src/v0_7/api/mod.rs index 0e73ec6853..ef1d1f6879 100644 --- a/crates/papyrus_rpc/src/v0_7/api/mod.rs +++ b/crates/papyrus_rpc/src/v0_7/api/mod.rs @@ -20,7 +20,10 @@ use papyrus_storage::StorageTxn; use serde::{Deserialize, Serialize}; use starknet_api::block::BlockNumber; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; -use starknet_api::deprecated_contract_class::Program; +use starknet_api::deprecated_contract_class::{ + ContractClass as StarknetApiDeprecatedContractClass, + Program, +}; use starknet_api::hash::StarkFelt; use starknet_api::state::{StateNumber, StorageKey}; use starknet_api::transaction::{EventKey, Fee, TransactionHash, TransactionOffsetInBlock}; @@ -260,7 +263,7 @@ pub trait JsonRpc { &self, block_id: BlockId, class_hash: ClassHash, - ) -> RpcResult; + ) -> RpcResult; } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -670,3 +673,9 @@ pub struct TransactionTraceWithHash { pub transaction_hash: TransactionHash, pub trace_root: TransactionTrace, } + +#[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)] +pub enum CompiledContractClass { + V0(StarknetApiDeprecatedContractClass), + V1(CasmContractClass), +} diff --git a/crates/papyrus_rpc/src/v0_7/api/test.rs b/crates/papyrus_rpc/src/v0_7/api/test.rs index 3a25351dd6..ee21d15b90 100644 --- a/crates/papyrus_rpc/src/v0_7/api/test.rs +++ b/crates/papyrus_rpc/src/v0_7/api/test.rs @@ -52,6 +52,7 @@ use starknet_api::core::{ }; use starknet_api::data_availability::L1DataAvailabilityMode; use starknet_api::deprecated_contract_class::{ + ContractClass as StarknetApiDeprecatedContractClass, ContractClassAbiEntry, FunctionAbiEntry, FunctionStateMutability, @@ -190,6 +191,7 @@ use crate::test_utils::{ validate_schema, SpecFile, }; +use crate::v0_7::api::CompiledContractClass; use crate::version_config::VERSION_0_7 as VERSION; use crate::{ internal_server_error, @@ -3567,35 +3569,52 @@ async fn get_compiled_contract_class() { let (module, mut storage_writer) = get_test_rpc_server_and_storage_writer_from_params::< JsonRpcServerImpl, >(None, None, None, None, None); - let class_hash = ClassHash(stark_felt!("0x1")); + let casm_class_hash = ClassHash(stark_felt!("0x1")); let casm_contract_class = CasmContractClass::get_test_instance(&mut get_rng()); + let deprecated_class_hash = ClassHash(stark_felt!("0x2")); + let deprecated_contract_class = + StarknetApiDeprecatedContractClass::get_test_instance(&mut get_rng()); storage_writer .begin_rw_txn() .unwrap() .append_state_diff( BlockNumber(0), starknet_api::state::ThinStateDiff { - declared_classes: IndexMap::from([(class_hash, CompiledClassHash::default())]), + declared_classes: IndexMap::from([ + (casm_class_hash, CompiledClassHash::default()), + (deprecated_class_hash, CompiledClassHash::default()), + ]), ..Default::default() }, ) .unwrap() - .append_casm(&class_hash, &casm_contract_class) + .append_casm(&casm_class_hash, &casm_contract_class) + .unwrap() + .append_classes(BlockNumber(0), &[], &[(deprecated_class_hash, &deprecated_contract_class)]) .unwrap() .commit() .unwrap(); let res = module - .call::<_, CasmContractClass>(method_name, (BlockId::Tag(Tag::Latest), class_hash)) + .call::<_, CompiledContractClass>(method_name, (BlockId::Tag(Tag::Latest), casm_class_hash)) + .await + .unwrap(); + assert_eq!(res, CompiledContractClass::V1(casm_contract_class)); + + let res = module + .call::<_, CompiledContractClass>( + method_name, + (BlockId::Tag(Tag::Latest), deprecated_class_hash), + ) .await .unwrap(); - assert_eq!(res, casm_contract_class); + assert_eq!(res, CompiledContractClass::V0(deprecated_contract_class)); // Ask for an invalid class hash. let err = module - .call::<_, CasmContractClass>( + .call::<_, CompiledContractClass>( method_name, - (BlockId::Tag(Tag::Latest), ClassHash(stark_felt!("0x2"))), + (BlockId::Tag(Tag::Latest), ClassHash(stark_felt!("0x3"))), ) .await .unwrap_err();