From 7098b96a4fe35e5b5836fdc5c0f8fe8b34931fe0 Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Tue, 14 Apr 2026 15:33:54 +0200 Subject: [PATCH 1/8] refactor(common/l2): add serialized class newtypes --- crates/common/src/class_definition.rs | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/crates/common/src/class_definition.rs b/crates/common/src/class_definition.rs index 056eb4e6b9..ac174f187b 100644 --- a/crates/common/src/class_definition.rs +++ b/crates/common/src/class_definition.rs @@ -12,6 +12,15 @@ use crate::{ByteCodeOffset, EntryPoint}; pub const CLASS_DEFINITION_MAX_ALLOWED_SIZE: u64 = 4 * 1024 * 1024; +#[derive(Clone, Debug, Default)] +struct SerializedSierraDefinition(Vec); + +#[derive(Clone, Debug, Default)] +struct SerializedCasmDefinition(Vec); + +#[derive(Clone, Debug, Default)] +struct SerializedCairoDefinition(Vec); + #[derive(Debug, Deserialize, Dummy)] pub enum ClassDefinition<'a> { Sierra(Sierra<'a>), @@ -190,3 +199,45 @@ pub struct SelectorAndFunctionIndex { pub selector: EntryPoint, pub function_idx: u64, } + +impl SerializedSierraDefinition { + pub fn from_bytes(bytes: Vec) -> Self { + Self(bytes) + } + + pub fn into_bytes(self) -> Vec { + self.0 + } + + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } +} + +impl SerializedCasmDefinition { + pub fn from_bytes(bytes: Vec) -> Self { + Self(bytes) + } + + pub fn into_bytes(self) -> Vec { + self.0 + } + + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } +} + +impl SerializedCairoDefinition { + pub fn from_bytes(bytes: Vec) -> Self { + Self(bytes) + } + + pub fn into_bytes(self) -> Vec { + self.0 + } + + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } +} From f61a830d90930c453cbc43feaaa626ec0c9f2e85 Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Tue, 14 Apr 2026 16:27:52 +0200 Subject: [PATCH 2/8] refactor(storage/class): remove dead code --- crates/storage/src/connection/class.rs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/crates/storage/src/connection/class.rs b/crates/storage/src/connection/class.rs index 330e6af533..47a3008231 100644 --- a/crates/storage/src/connection/class.rs +++ b/crates/storage/src/connection/class.rs @@ -209,18 +209,7 @@ impl Transaction<'_> { Ok(Some((block_number, definition))) } - /// Returns the compressed class definition if it has been declared at - /// `block_id`. - pub fn compressed_class_definition_at( - &self, - block_id: BlockId, - class_hash: ClassHash, - ) -> anyhow::Result>> { - self.compressed_class_definition_at_with_block_number(block_id, class_hash) - .map(|option| option.map(|(_block_number, definition)| definition)) - } - - pub fn compressed_class_definition_at_with_block_number( + fn compressed_class_definition_at_with_block_number( &self, block_id: BlockId, class_hash: ClassHash, From d6b96599f4edb7585c01c7bcc564706ff308d6a8 Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Tue, 14 Apr 2026 16:07:34 +0200 Subject: [PATCH 3/8] refactor: use serialized class newtypes --- crates/class-hash/src/lib.rs | 102 ++++++---- crates/common/src/casm_class.rs | 10 +- crates/common/src/class_definition.rs | 102 +++++++++- crates/common/src/l2.rs | 5 +- crates/compiler/src/lib.rs | 113 ++++++----- crates/executor/src/class.rs | 13 +- crates/executor/src/state_reader.rs | 28 +-- crates/executor/src/state_reader/native.rs | 23 ++- .../src/state_reader/storage_adapter.rs | 12 +- .../storage_adapter/concurrent.rs | 78 +++++--- .../src/state_reader/storage_adapter/rc.rs | 16 +- crates/feeder-gateway/src/main.rs | 9 +- crates/gateway-client/src/lib.rs | 25 ++- crates/p2p/src/sync/client/conv.rs | 15 +- crates/p2p/src/sync/client/peer_agnostic.rs | 25 +-- .../src/sync/client/peer_agnostic/fixtures.rs | 7 +- crates/p2p/src/sync/client/types.rs | 15 +- .../pathfinder/examples/compute_class_hash.rs | 11 +- .../examples/recompute_casm_class_hashes.rs | 5 +- crates/pathfinder/src/bin/pathfinder/main.rs | 8 +- crates/pathfinder/src/devnet/class.rs | 13 +- .../src/p2p_network/sync/sync_handlers.rs | 21 ++- .../p2p_network/sync/sync_handlers/tests.rs | 11 +- crates/pathfinder/src/state/sync.rs | 38 +++- crates/pathfinder/src/state/sync/class.rs | 39 ++-- crates/pathfinder/src/state/sync/l2.rs | 25 ++- crates/pathfinder/src/state/sync/repair.rs | 22 ++- crates/pathfinder/src/sync.rs | 26 ++- crates/pathfinder/src/sync/checkpoint.rs | 42 +++-- .../pathfinder/src/sync/class_definitions.rs | 34 ++-- crates/rpc/src/executor.rs | 25 ++- crates/rpc/src/lib.rs | 65 +++++-- .../rpc/src/method/add_declare_transaction.rs | 11 +- crates/rpc/src/method/call.rs | 28 ++- crates/rpc/src/method/estimate_fee.rs | 7 +- crates/rpc/src/method/estimate_message_fee.rs | 8 +- crates/rpc/src/method/get_class.rs | 2 +- crates/rpc/src/method/get_class_at.rs | 2 +- crates/rpc/src/method/get_compiled_casm.rs | 18 +- .../rpc/src/method/simulate_transactions.rs | 7 +- .../src/method/trace_block_transactions.rs | 16 +- crates/rpc/src/test_setup.rs | 23 ++- crates/rpc/src/types/class.rs | 43 ++++- crates/storage/src/connection/block.rs | 4 +- crates/storage/src/connection/class.rs | 177 ++++++++++++------ crates/storage/src/connection/state_update.rs | 45 +++-- crates/storage/src/fake.rs | 32 +++- crates/storage/src/schema/revision_0076.rs | 8 +- crates/validator/src/lib.rs | 8 +- 49 files changed, 951 insertions(+), 471 deletions(-) diff --git a/crates/class-hash/src/lib.rs b/crates/class-hash/src/lib.rs index 2400fe0097..e331cdf3fc 100644 --- a/crates/class-hash/src/lib.rs +++ b/crates/class-hash/src/lib.rs @@ -58,6 +58,12 @@ use anyhow::{Context, Error, Result}; use pathfinder_common::class_definition::EntryPointType::*; +use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedClass, + SerializedClassDefinition, + SerializedSierraDefinition, +}; use pathfinder_common::{felt_bytes, ClassHash}; use pathfinder_crypto::hash::{HashChain, PoseidonHasher}; use pathfinder_crypto::Felt; @@ -80,22 +86,47 @@ impl ComputedClassHash { } } -/// Computes the starknet class hash for given class definition JSON blob. +/// Consumes an opaque serialized class definition and outputs the computed +/// class hash as well as the definition reinterpreted as either a serialized +/// Cairo or Sierra definition. /// /// This function first parses the JSON blob to decide if it's a Cairo or Sierra /// class definition and then calls the appropriate function to compute the /// class hash with the parsed definition. -pub fn compute_class_hash(contract_definition_dump: &[u8]) -> Result { - let contract_definition = parse_contract_definition(contract_definition_dump) +pub fn compute_class_hash( + serialized_definition: SerializedClassDefinition, +) -> Result<(ComputedClassHash, SerializedClass)> { + let contract_definition = parse_contract_definition(&serialized_definition) .context("Failed to parse contract definition")?; match contract_definition { json::ContractDefinition::Sierra(definition) => compute_sierra_class_hash(definition) .map(ComputedClassHash::Sierra) - .context("Compute class hash"), + .context("Compute class hash") + .map(|hash| { + ( + hash, + // It is safe to reinterpret the serialized definition as a Sierra definition + // since the parsing step succeeded and confirmed it is a + // Sierra definition. + SerializedClass::Sierra(SerializedSierraDefinition::from_bytes( + serialized_definition.into_bytes(), + )), + ) + }), json::ContractDefinition::Cairo(definition) => compute_cairo_class_hash(definition.into()) .map(ComputedClassHash::Cairo) - .context("Compute class hash"), + .context("Compute class hash") + .map(|hash| { + ( + hash, + // It is safe to reinterpret the serialized definition as a Cairo definition + // since the parsing step succeeded and confirmed it is a Cairo definition. + SerializedClass::Cairo(SerializedCairoDefinition::from_bytes( + serialized_definition.into_bytes(), + )), + ) + }), } } @@ -132,14 +163,16 @@ pub fn compute_cairo_hinted_class_hash( /// /// Due to an issue in serde_json we can't use an untagged enum and simply /// derive a Deserialize implementation: -pub fn parse_contract_definition( - contract_definition_dump: &[u8], +fn parse_contract_definition( + serialized_definition: &SerializedClassDefinition, ) -> serde_json::Result> { - serde_json::from_slice::>(contract_definition_dump) + serde_json::from_slice::>(serialized_definition.as_bytes()) .map(json::ContractDefinition::Sierra) .or_else(|_| { - serde_json::from_slice::>(contract_definition_dump) - .map(json::ContractDefinition::Cairo) + serde_json::from_slice::>( + serialized_definition.as_bytes(), + ) + .map(json::ContractDefinition::Cairo) }) } @@ -799,17 +832,22 @@ pub mod json { #[cfg(test)] mod test_vectors { + use pathfinder_common::class_definition::SerializedClassDefinition; use pathfinder_common::macro_prelude::*; use starknet_gateway_test_fixtures::class_definitions::*; use super::super::{compute_class_hash, ComputedClassHash}; + fn hash(data: &[u8]) -> ComputedClassHash { + compute_class_hash(SerializedClassDefinition::from_slice(data)) + .unwrap() + .0 + } + #[tokio::test] async fn first() { - let hash = compute_class_hash(INTEGRATION_TEST).unwrap(); - assert_eq!( - hash, + hash(INTEGRATION_TEST), ComputedClassHash::Cairo(class_hash!( "0x031da92cf5f54bcb81b447e219e2b791b23f3052d12b6c9abd04ff2e5626576" )) @@ -818,10 +856,8 @@ pub mod json { #[test] fn second() { - let hash = super::super::compute_class_hash(CONTRACT_DEFINITION).unwrap(); - assert_eq!( - hash, + hash(CONTRACT_DEFINITION), ComputedClassHash::Cairo(class_hash!( "0x50b2148c0d782914e0b12a1a32abe5e398930b7e914f82c65cb7afce0a0ab9b" )) @@ -830,10 +866,8 @@ pub mod json { #[tokio::test] async fn genesis_contract() { - let hash = compute_class_hash(GOERLI_GENESIS).unwrap(); - assert_eq!( - hash, + hash(GOERLI_GENESIS), ComputedClassHash::Cairo(class_hash!( "0x10455c752b86932ce552f2b0fe81a880746649b9aee7e0d842bf3f52378f9f8" )) @@ -851,10 +885,11 @@ pub mod json { // Known contract which triggered a hash mismatch failure. let extract = tokio::task::spawn_blocking(move || -> anyhow::Result<_> { - let hash = compute_class_hash(CAIRO_0_8_NEW_ATTRIBUTES)?; - Ok(hash) + Ok(compute_class_hash(SerializedClassDefinition::from_slice( + CAIRO_0_8_NEW_ATTRIBUTES, + ))?) }); - let calculated_hash = extract.await.unwrap().unwrap(); + let (calculated_hash, _) = extract.await.unwrap().unwrap(); assert_eq!(calculated_hash, expected); } @@ -863,10 +898,8 @@ pub mod json { async fn cairo_0_10() { // Contract whose class triggered a deserialization issue because of the new // `compiler_version` property. - let hash = compute_class_hash(CAIRO_0_10_COMPILER_VERSION).unwrap(); - assert_eq!( - hash, + hash(CAIRO_0_10_COMPILER_VERSION), ComputedClassHash::Cairo(class_hash!( "0xa69700a89b1fa3648adff91c438b79c75f7dcb0f4798938a144cce221639d6" )) @@ -878,10 +911,8 @@ pub mod json { // Contract who's class contains `compiler_version` property as well as // `cairo_type` with tuple values. These tuple values require a // space to be injected in order to achieve the correct hash. - let hash = compute_class_hash(CAIRO_0_10_TUPLES_INTEGRATION).unwrap(); - assert_eq!( - hash, + hash(CAIRO_0_10_TUPLES_INTEGRATION), ComputedClassHash::Cairo(class_hash!( "0x542460935cea188d21e752d8459d82d60497866aaad21f873cbb61621d34f7f" )) @@ -893,10 +924,8 @@ pub mod json { // Contract who's class contains `compiler_version` property as well as // `cairo_type` with tuple values. These tuple values require a // space to be injected in order to achieve the correct hash. - let hash = compute_class_hash(CAIRO_0_10_TUPLES_GOERLI).unwrap(); - assert_eq!( - hash, + hash(CAIRO_0_10_TUPLES_GOERLI), ComputedClassHash::Cairo(class_hash!( "0x66af14b94491ba4e2aea1117acf0a3155c53d92fdfd9c1f1dcac90dc2d30157" )) @@ -905,10 +934,8 @@ pub mod json { #[tokio::test] async fn cairo_0_11_sierra() { - let hash = compute_class_hash(CAIRO_0_11_SIERRA).unwrap(); - assert_eq!( - hash, + hash(CAIRO_0_11_SIERRA), ComputedClassHash::Sierra(class_hash!( "0x4e70b19333ae94bd958625f7b61ce9eec631653597e68645e13780061b2136c" )) @@ -917,14 +944,17 @@ pub mod json { #[tokio::test] async fn cairo_0_11_with_decimal_entry_point_offset() { - let hash = compute_class_hash(CAIRO_0_11_WITH_DECIMAL_ENTRY_POINT_OFFSET).unwrap(); + let (hash, _) = compute_class_hash(SerializedClassDefinition::from_slice( + CAIRO_0_11_WITH_DECIMAL_ENTRY_POINT_OFFSET, + )) + .unwrap(); assert_eq!( hash, ComputedClassHash::Cairo(class_hash!( "0x0484c163658bcce5f9916f486171ac60143a92897533aa7ff7ac800b16c63311" )) - ) + ); } } diff --git a/crates/common/src/casm_class.rs b/crates/common/src/casm_class.rs index 2385410edf..dc2fabecdf 100644 --- a/crates/common/src/casm_class.rs +++ b/crates/common/src/casm_class.rs @@ -90,10 +90,10 @@ pub enum NestedIntList { Node(Vec), } -impl TryFrom<&str> for CasmContractClass { - type Error = serde_json::Error; - - fn try_from(value: &str) -> Result { - serde_json::from_str(value) +impl CasmContractClass { + pub fn try_from_serialized_definition( + definition: &crate::class_definition::SerializedCasmDefinition, + ) -> Result { + serde_json::from_slice(definition.as_bytes()) } } diff --git a/crates/common/src/class_definition.rs b/crates/common/src/class_definition.rs index ac174f187b..1abff4a59b 100644 --- a/crates/common/src/class_definition.rs +++ b/crates/common/src/class_definition.rs @@ -12,14 +12,27 @@ use crate::{ByteCodeOffset, EntryPoint}; pub const CLASS_DEFINITION_MAX_ALLOWED_SIZE: u64 = 4 * 1024 * 1024; -#[derive(Clone, Debug, Default)] -struct SerializedSierraDefinition(Vec); - -#[derive(Clone, Debug, Default)] -struct SerializedCasmDefinition(Vec); - -#[derive(Clone, Debug, Default)] -struct SerializedCairoDefinition(Vec); +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +pub struct SerializedSierraDefinition(Vec); + +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +pub struct SerializedCasmDefinition(Vec); + +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +pub struct SerializedCairoDefinition(Vec); + +/// Carries the definition of a serialized contract class, either Sierra or +/// Cairo. The caller does not care which class definition it is. +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +pub struct SerializedClassDefinition(Vec); + +/// Carries the definition of a serialized contract class, either Sierra or +/// Cairo. +#[derive(Clone, Debug)] +pub enum SerializedClass { + Sierra(SerializedSierraDefinition), + Cairo(SerializedCairoDefinition), +} #[derive(Debug, Deserialize, Dummy)] pub enum ClassDefinition<'a> { @@ -205,6 +218,10 @@ impl SerializedSierraDefinition { Self(bytes) } + pub fn from_slice(bytes: &[u8]) -> Self { + Self(bytes.to_vec()) + } + pub fn into_bytes(self) -> Vec { self.0 } @@ -219,6 +236,10 @@ impl SerializedCasmDefinition { Self(bytes) } + pub fn from_slice(bytes: &[u8]) -> Self { + Self(bytes.to_vec()) + } + pub fn into_bytes(self) -> Vec { self.0 } @@ -233,6 +254,28 @@ impl SerializedCairoDefinition { Self(bytes) } + pub fn from_slice(bytes: &[u8]) -> Self { + Self(bytes.to_vec()) + } + + pub fn into_bytes(self) -> Vec { + self.0 + } + + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } +} + +impl SerializedClassDefinition { + pub fn from_bytes(bytes: Vec) -> Self { + Self(bytes) + } + + pub fn from_slice(bytes: &[u8]) -> Self { + Self(bytes.to_vec()) + } + pub fn into_bytes(self) -> Vec { self.0 } @@ -240,4 +283,47 @@ impl SerializedCairoDefinition { pub fn as_bytes(&self) -> &[u8] { &self.0 } + +} + +/// We can use `From` because this is always safe. +impl From for SerializedClassDefinition { + fn from(d: SerializedSierraDefinition) -> Self { + Self::from_bytes(d.into_bytes()) + } +} + +/// We can use `From` because this is always safe. +impl From for SerializedClassDefinition { + fn from(d: SerializedCairoDefinition) -> Self { + Self::from_bytes(d.into_bytes()) + } +} + +// TODO derive? +impl Dummy for SerializedSierraDefinition { + fn dummy_with_rng(_: &T, rng: &mut R) -> Self { + Self(Faker.fake_with_rng(rng)) + } +} + +// TODO derive? +impl Dummy for SerializedCasmDefinition { + fn dummy_with_rng(_: &T, rng: &mut R) -> Self { + Self(Faker.fake_with_rng(rng)) + } +} + +// TODO derive? +impl Dummy for SerializedCairoDefinition { + fn dummy_with_rng(_: &T, rng: &mut R) -> Self { + Self(Faker.fake_with_rng(rng)) + } +} + +// TODO derive? +impl Dummy for SerializedClassDefinition { + fn dummy_with_rng(_: &T, rng: &mut R) -> Self { + Self(Faker.fake_with_rng(rng)) + } } diff --git a/crates/common/src/l2.rs b/crates/common/src/l2.rs index aebf4c8d8e..fdc2a448fd 100644 --- a/crates/common/src/l2.rs +++ b/crates/common/src/l2.rs @@ -3,6 +3,7 @@ use std::sync::{Arc, RwLock}; use fake::Dummy; +use crate::class_definition::{SerializedCasmDefinition, SerializedSierraDefinition}; use crate::event::Event; use crate::receipt::Receipt; use crate::state_update::StateUpdateData; @@ -97,8 +98,8 @@ pub struct ConsensusFinalizedBlockHeader { pub struct DeclaredClass { pub sierra_hash: SierraHash, pub casm_hash_v2: CasmHash, - pub sierra_def: Vec, - pub casm_def: Vec, + pub sierra_def: SerializedSierraDefinition, + pub casm_def: SerializedCasmDefinition, } impl From for L2BlockToCommit { diff --git a/crates/compiler/src/lib.rs b/crates/compiler/src/lib.rs index ac59c9e80a..feea965c9f 100644 --- a/crates/compiler/src/lib.rs +++ b/crates/compiler/src/lib.rs @@ -1,7 +1,8 @@ use std::io::Write; use anyhow::Context; -use pathfinder_common::{class_definition, felt, CasmHash}; +use pathfinder_common::class_definition::{self, SerializedCasmDefinition}; +use pathfinder_common::{felt, CasmHash}; use pathfinder_crypto::Felt; /// Resource limits for the compiler child process. @@ -102,10 +103,10 @@ impl std::fmt::Display for BlockifierLibfuncs { /// non-Unix platforms no resource limits are applied; the child process still /// runs but without any resource constraints. pub fn compile_sierra_to_casm( - sierra_definition: &[u8], + sierra_definition: &class_definition::SerializedSierraDefinition, resource_limits: ResourceLimits, blockifier_libfuncs: BlockifierLibfuncs, -) -> anyhow::Result> { +) -> anyhow::Result { let mut pathfinder_cmd = pathfinder_exe() .context("reading pathfinder executable path") .map(std::process::Command::new)?; @@ -126,7 +127,7 @@ pub fn compile_sierra_to_casm( { let mut ch_stdin = child.stdin.take().context("opening child stdin")?; ch_stdin - .write_all(sierra_definition) + .write_all(sierra_definition.as_bytes()) .context("writing Sierra definition to child stdin")?; ch_stdin.flush().context("flushing child stdin")?; } @@ -144,7 +145,7 @@ pub fn compile_sierra_to_casm( ); } - Ok(output.stdout) + Ok(SerializedCasmDefinition::from_bytes(output.stdout)) } /// Compile a Sierra class definition into CASM using an isolated child process. @@ -159,11 +160,15 @@ pub fn compile_sierra_to_casm_deser( sierra_definition: class_definition::Sierra<'_>, resource_limits: ResourceLimits, blockifier_libfuncs: BlockifierLibfuncs, -) -> anyhow::Result> { +) -> anyhow::Result { serde_json::to_vec(&sierra_definition) .context("serializing Sierra definition") .map(|sierra_definition| { - compile_sierra_to_casm(&sierra_definition, resource_limits, blockifier_libfuncs) + compile_sierra_to_casm( + &class_definition::SerializedSierraDefinition::from_bytes(sierra_definition), + resource_limits, + blockifier_libfuncs, + ) })? } @@ -305,14 +310,14 @@ mod spawn { /// which is not recommended. Use [`compile_sierra_to_casm`] to compile in an /// isolated child process with resource limits. pub fn compile_sierra_to_casm_impl( - sierra_definition: &[u8], + sierra_definition: &class_definition::SerializedSierraDefinition, blockifier_libfuncs: BlockifierLibfuncs, -) -> anyhow::Result> { +) -> anyhow::Result { // The class representation expected by the compiler doesn't match the // representation used by the feeder gateway for Sierra classes, so we have to // convert the JSON to something that can be parsed into the expected input // format for the compiler. - serde_json::from_slice::>(sierra_definition) + serde_json::from_slice::>(sierra_definition.as_bytes()) .context("Parsing Sierra class") .map(|sierra_class| compile_sierra_to_casm_deser_impl(sierra_class, blockifier_libfuncs))? .context("Compiling Sierra to CASM") @@ -326,7 +331,7 @@ pub fn compile_sierra_to_casm_impl( pub fn compile_sierra_to_casm_deser_impl( sierra_definition: class_definition::Sierra<'_>, blockifier_libfuncs: BlockifierLibfuncs, -) -> anyhow::Result> { +) -> anyhow::Result { let version = parse_sierra_version(&sierra_definition.sierra_program) .context("Parsing Sierra version")?; @@ -379,8 +384,8 @@ fn parse_sierra_version(program: &[Felt]) -> anyhow::Result { /// Parse CASM class definition and return _Blake2_ CASM class hash. /// /// Uses the _latest_ compiler for the parsing and starknet_api for the hashing. -pub fn casm_class_hash_v2(casm_definition: &[u8]) -> anyhow::Result { - v2::casm_class_hash_v2(casm_definition) +pub fn casm_class_hash_v2(casm_definition: &SerializedCasmDefinition) -> anyhow::Result { + v2::casm_class_hash_v2(casm_definition.as_bytes()) } mod v1_0_0_alpha6 { @@ -405,17 +410,15 @@ mod v1_0_0_alpha6 { serde_json::from_value::(json) } - pub(super) fn compile(definition: class_definition::Sierra<'_>) -> anyhow::Result> { + pub(super) fn compile( + definition: class_definition::Sierra<'_>, + ) -> anyhow::Result { let sierra_class: ContractClass = pathfinder_to_starknet_contract_class(definition) .context("Converting to Sierra class")?; validate_compatible_sierra_version( &sierra_class, ListSelector::ListName( - // Keeping the "experimental" list for backwards - // compatibility. Also, the names in - // BlockifierLibfuncs would have to be mapped to - // (audited|testnet|experimental)_v0.1.0 . casm_compiler_v1_0_0_alpha6::allowed_libfuncs::DEFAULT_EXPERIMENTAL_LIBFUNCS_LIST .to_string(), ), @@ -424,9 +427,9 @@ mod v1_0_0_alpha6 { let casm_class = CasmContractClass::from_contract_class(sierra_class, true) .context("Compiling to CASM")?; - let casm_definition = serde_json::to_vec(&casm_class)?; - - Ok(casm_definition) + Ok(super::SerializedCasmDefinition::from_bytes( + serde_json::to_vec(&casm_class)?, + )) } } @@ -452,17 +455,15 @@ mod v1_0_0_rc0 { serde_json::from_value::(json) } - pub(super) fn compile(definition: class_definition::Sierra<'_>) -> anyhow::Result> { + pub(super) fn compile( + definition: class_definition::Sierra<'_>, + ) -> anyhow::Result { let sierra_class: ContractClass = pathfinder_to_starknet_contract_class(definition) .context("Converting to Sierra class")?; validate_compatible_sierra_version( &sierra_class, ListSelector::ListName( - // Keeping the "experimental" list for backwards - // compatibility. Also, the names in - // BlockifierLibfuncs would have to be mapped to - // (audited|testnet|experimental)_v0.1.0 . casm_compiler_v1_0_0_rc0::allowed_libfuncs::DEFAULT_EXPERIMENTAL_LIBFUNCS_LIST .to_string(), ), @@ -471,9 +472,9 @@ mod v1_0_0_rc0 { let casm_class = CasmContractClass::from_contract_class(sierra_class, true) .context("Compiling to CASM")?; - let casm_definition = serde_json::to_vec(&casm_class)?; - - Ok(casm_definition) + Ok(super::SerializedCasmDefinition::from_bytes( + serde_json::to_vec(&casm_class)?, + )) } } @@ -499,17 +500,15 @@ mod v1_1_1 { serde_json::from_value::(json) } - pub(super) fn compile(definition: class_definition::Sierra<'_>) -> anyhow::Result> { + pub(super) fn compile( + definition: class_definition::Sierra<'_>, + ) -> anyhow::Result { let sierra_class: ContractClass = pathfinder_to_starknet_contract_class(definition) .context("Converting to Sierra class")?; validate_compatible_sierra_version( &sierra_class, ListSelector::ListName( - // Keeping the "experimental" list for backwards - // compatibility. Also, the names in - // BlockifierLibfuncs would have to be mapped to - // (audited|testnet|experimental)_v0.1.0 . casm_compiler_v1_0_0_rc0::allowed_libfuncs::DEFAULT_EXPERIMENTAL_LIBFUNCS_LIST .to_string(), ), @@ -518,9 +517,9 @@ mod v1_1_1 { let casm_class = CasmContractClass::from_contract_class(sierra_class, true) .context("Compiling to CASM")?; - let casm_definition = serde_json::to_vec(&casm_class)?; - - Ok(casm_definition) + Ok(super::SerializedCasmDefinition::from_bytes( + serde_json::to_vec(&casm_class)?, + )) } } @@ -547,7 +546,7 @@ mod v2 { pub(super) fn compile( definition: crate::class_definition::Sierra<'_>, blockifier_libfuncs: BlockifierLibfuncs, - ) -> anyhow::Result> { + ) -> anyhow::Result { let sierra_class: ContractClass = pathfinder_to_starknet_contract_class(definition) .context("Converting to Sierra class")?; @@ -571,9 +570,9 @@ mod v2 { usize::MAX, ) .context("Compiling to CASM")?; - let casm_definition = serde_json::to_vec(&casm_class)?; - - Ok(casm_definition) + Ok(super::SerializedCasmDefinition::from_bytes( + serde_json::to_vec(&casm_class)?, + )) } pub(super) fn casm_class_hash_v2(casm_definition: &[u8]) -> anyhow::Result { @@ -644,8 +643,13 @@ mod tests { #[test] fn test_compile_ser() { - compile_sierra_to_casm_impl(CAIRO_1_0_0_ALPHA5_SIERRA, BlockifierLibfuncs::default()) - .unwrap(); + compile_sierra_to_casm_impl( + &class_definition::SerializedSierraDefinition::from_slice( + CAIRO_1_0_0_ALPHA5_SIERRA, + ), + BlockifierLibfuncs::default(), + ) + .unwrap(); } } @@ -669,8 +673,11 @@ mod tests { #[test] fn test_compile_ser() { - compile_sierra_to_casm_impl(CAIRO_1_0_0_RC0_SIERRA, BlockifierLibfuncs::default()) - .unwrap(); + compile_sierra_to_casm_impl( + &class_definition::SerializedSierraDefinition::from_slice(CAIRO_1_0_0_RC0_SIERRA), + BlockifierLibfuncs::default(), + ) + .unwrap(); } } @@ -697,15 +704,23 @@ mod tests { #[test] fn test_compile_ser() { - compile_sierra_to_casm_impl(CAIRO_1_1_0_RC0_SIERRA, BlockifierLibfuncs::default()) - .unwrap(); + compile_sierra_to_casm_impl( + &class_definition::SerializedSierraDefinition::from_slice(CAIRO_1_1_0_RC0_SIERRA), + BlockifierLibfuncs::default(), + ) + .unwrap(); } #[test] fn regression_stack_overflow() { // This class caused a stack-overflow in v2 compilers <= v2.0.1 - compile_sierra_to_casm_impl(CAIRO_2_0_0_STACK_OVERFLOW, BlockifierLibfuncs::default()) - .unwrap(); + compile_sierra_to_casm_impl( + &class_definition::SerializedSierraDefinition::from_slice( + CAIRO_2_0_0_STACK_OVERFLOW, + ), + BlockifierLibfuncs::default(), + ) + .unwrap(); } } } diff --git a/crates/executor/src/class.rs b/crates/executor/src/class.rs index ec39d4ebb8..2a246bbafa 100644 --- a/crates/executor/src/class.rs +++ b/crates/executor/src/class.rs @@ -1,23 +1,20 @@ use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; +use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedClassDefinition}; pub fn parse_deprecated_class_definition( - definition: Vec, + definition: SerializedClassDefinition, ) -> anyhow::Result { - let definition = String::from_utf8(definition)?; - let class: starknet_api::deprecated_contract_class::ContractClass = - serde_json::from_str(&definition)?; + serde_json::from_slice(definition.as_bytes())?; Ok(starknet_api::contract_class::ContractClass::V0(class)) } pub fn parse_casm_definition( - casm_definition: Vec, + casm_definition: SerializedCasmDefinition, sierra_version: starknet_api::contract_class::SierraVersion, ) -> anyhow::Result { - let casm_definition = String::from_utf8(casm_definition)?; - - let class: CasmContractClass = serde_json::from_str(&casm_definition)?; + let class: CasmContractClass = serde_json::from_slice(casm_definition.as_bytes())?; Ok(starknet_api::contract_class::ContractClass::V1(( class, diff --git a/crates/executor/src/state_reader.rs b/crates/executor/src/state_reader.rs index 976d440621..abfa6ab28c 100644 --- a/crates/executor/src/state_reader.rs +++ b/crates/executor/src/state_reader.rs @@ -4,6 +4,7 @@ use blockifier::execution::contract_class::RunnableCompiledClass; use blockifier::state::errors::StateError; use blockifier::state::state_api::StateReader; use cached::Cached; +use pathfinder_common::class_definition::SerializedClassDefinition; use pathfinder_common::{BlockNumber, ClassHash, StorageAddress, StorageValue}; use pathfinder_crypto::Felt; use starknet_api::contract_class::compiled_class_hash::{HashVersion, HashableCompiledClass}; @@ -121,7 +122,7 @@ impl PathfinderStateReader { Some(casm_definition) => { // There's a CASM definition in storage, so this is a Sierra class. Extract // class version from program. - let sierra_version = self.sierra_version_from_class(&class_definition)?; + let sierra_version = self.try_sierra_version_from_class(&class_definition)?; #[cfg(feature = "cairo-native")] let runnable_class = if self.native_execution_force_use_for_incompatible_classes @@ -160,15 +161,16 @@ impl PathfinderStateReader { } None => { // No CASM definition means this is a legacy Cairo 0 class. - let class_definition = String::from_utf8(class_definition).map_err(|error| { - StateError::StateReadError(format!( - "Class definition is not valid UTF-8: {error}" - )) - })?; + let class_definition = + std::str::from_utf8(class_definition.as_bytes()).map_err(|error| { + StateError::StateReadError(format!( + "Class definition is not valid UTF-8: {error}" + )) + })?; let class = blockifier::execution::contract_class::CompiledClassV0::try_from_json_string( - &class_definition, + class_definition, ) .map_err(StateError::ProgramError)?; @@ -177,14 +179,14 @@ impl PathfinderStateReader { } } - fn sierra_version_from_class( + fn try_sierra_version_from_class( &self, - class_definition: &[u8], + class_definition: &SerializedClassDefinition, ) -> Result { use cairo_vm::types::errors::program_errors::ProgramError; let sierra_class: pathfinder_common::class_definition::Sierra<'_> = - serde_json::from_slice(class_definition) + serde_json::from_slice(class_definition.as_bytes()) .map_err(|error| StateError::ProgramError(ProgramError::Parse(error)))?; SierraVersion::extract_from_program(&sierra_class.sierra_program).map_err(Into::into) } @@ -192,13 +194,13 @@ impl PathfinderStateReader { fn sierra_class_as_casm( sierra_version: SierraVersion, - casm_definition: Vec, + casm_definition: pathfinder_common::class_definition::SerializedCasmDefinition, ) -> Result { - let casm_definition = String::from_utf8(casm_definition).map_err(|error| { + let casm_definition = std::str::from_utf8(casm_definition.as_bytes()).map_err(|error| { StateError::StateReadError(format!("CASM definition is not valid UTF-8: {error}")) })?; let casm_class = blockifier::execution::contract_class::CompiledClassV1::try_from_json_string( - &casm_definition, + casm_definition, sierra_version, ) .map_err(StateError::ProgramError)?; diff --git a/crates/executor/src/state_reader/native.rs b/crates/executor/src/state_reader/native.rs index 1dcf273aea..0f0ce241da 100644 --- a/crates/executor/src/state_reader/native.rs +++ b/crates/executor/src/state_reader/native.rs @@ -6,6 +6,7 @@ use blockifier::state::errors::StateError; use cached::{Cached, SizedCache}; use cairo_native::executor::AotContractExecutor; use cairo_vm::types::errors::program_errors::ProgramError; +use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedClassDefinition}; use pathfinder_common::ClassHash; use starknet_api::contract_class::SierraVersion; use tokio_util::sync::CancellationToken; @@ -13,8 +14,8 @@ use tokio_util::sync::CancellationToken; struct CompilerInput { class_hash: ClassHash, sierra_version: SierraVersion, - class_definition: Vec, - casm_definition: Vec, + class_definition: SerializedClassDefinition, + casm_definition: SerializedCasmDefinition, } enum CacheItem { @@ -53,8 +54,8 @@ impl NativeClassCache { &self, class_hash: ClassHash, sierra_version: SierraVersion, - class_definition: Vec, - casm_definition: Vec, + class_definition: SerializedClassDefinition, + casm_definition: SerializedCasmDefinition, ) -> Option { let mut locked = self.cache.lock().unwrap(); @@ -137,8 +138,9 @@ fn sierra_class_as_native( input: CompilerInput, optimization_level: cairo_native::OptLevel, ) -> Result { - let mut sierra_definition: serde_json::Value = serde_json::from_slice(&input.class_definition) - .map_err(|e| StateError::ProgramError(ProgramError::Parse(e)))?; + let mut sierra_definition: serde_json::Value = + serde_json::from_slice(input.class_definition.as_bytes()) + .map_err(|e| StateError::ProgramError(ProgramError::Parse(e)))?; let sierra_abi_str = sierra_definition .get("abi") .ok_or_else(|| StateError::StateReadError("Sierra ABI is missing".to_owned()))? @@ -183,12 +185,13 @@ fn sierra_class_as_native( .map_err(|e| StateError::StateReadError(format!("Error compiling native class: {e:?}")))? .map_err(|e| StateError::StateReadError(format!("Error compiling native class: {e}")))?; - let casm_definition = String::from_utf8(input.casm_definition).map_err(|error| { - StateError::StateReadError(format!("Class definition is not valid UTF-8: {error}")) - })?; + let casm_definition = + std::str::from_utf8(input.casm_definition.as_bytes()).map_err(|error| { + StateError::StateReadError(format!("Class definition is not valid UTF-8: {error}")) + })?; let casm_class = blockifier::execution::contract_class::CompiledClassV1::try_from_json_string( - &casm_definition, + casm_definition, input.sierra_version, ) .map_err(StateError::ProgramError)?; diff --git a/crates/executor/src/state_reader/storage_adapter.rs b/crates/executor/src/state_reader/storage_adapter.rs index 61fbb94988..105d5d38a0 100644 --- a/crates/executor/src/state_reader/storage_adapter.rs +++ b/crates/executor/src/state_reader/storage_adapter.rs @@ -1,5 +1,6 @@ use blockifier::blockifier::config::TransactionExecutorConfig; use blockifier::state::errors::StateError; +use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedClassDefinition}; use pathfinder_common::{ BlockHash, BlockId, @@ -16,15 +17,18 @@ pub mod concurrent; pub mod rc; // Keep clippy happy -type ClassDefinitionAtWithBlockNumber = Option<(BlockNumber, Vec)>; -type ClassDefinitionWithBlockNumber = Option<(Option, Vec)>; +type ClassDefinitionAtWithBlockNumber = Option<(BlockNumber, SerializedClassDefinition)>; +type ClassDefinitionWithBlockNumber = Option<(Option, SerializedClassDefinition)>; pub trait StorageAdapter { fn transaction_executor_config(&self) -> TransactionExecutorConfig; fn block_hash(&self, block: BlockId) -> anyhow::Result>; - fn casm_definition(&self, class_hash: ClassHash) -> Result>, StateError>; + fn casm_definition( + &self, + class_hash: ClassHash, + ) -> Result, StateError>; fn class_definition_with_block_number( &self, @@ -35,7 +39,7 @@ pub trait StorageAdapter { &self, block_id: BlockId, class_hash: ClassHash, - ) -> Result>, StateError>; + ) -> Result, StateError>; fn class_definition_at_with_block_number( &self, diff --git a/crates/executor/src/state_reader/storage_adapter/concurrent.rs b/crates/executor/src/state_reader/storage_adapter/concurrent.rs index 4cf3e49291..1b5363a5b0 100644 --- a/crates/executor/src/state_reader/storage_adapter/concurrent.rs +++ b/crates/executor/src/state_reader/storage_adapter/concurrent.rs @@ -2,10 +2,10 @@ use std::sync::mpsc::{self, Receiver, Sender, SyncSender}; use blockifier::blockifier::config::{ConcurrencyConfig, TransactionExecutorConfig}; use blockifier::state::errors::StateError; +use pathfinder_common::class_definition::SerializedCasmDefinition; use pathfinder_common::{ BlockHash, BlockId, - BlockNumber, CasmHash, ClassHash, ContractAddress, @@ -32,7 +32,10 @@ pub struct ConcurrentStorageAdapter { enum Command { BlockHash(BlockId, SyncSender>>), - CasmDefinition(ClassHash, SyncSender>, StateError>>), + CasmDefinition( + ClassHash, + SyncSender, StateError>>, + ), ClassDefinitionWithBlockNumber( ClassHash, SyncSender>, @@ -40,7 +43,7 @@ enum Command { CasmDefinitionAt( BlockId, ClassHash, - SyncSender>, StateError>>, + SyncSender, StateError>>, ), ClassDefinitionAtWithBlockNumber( BlockId, @@ -126,7 +129,10 @@ impl StorageAdapter for ConcurrentStorageAdapter { rx.recv().expect("Channel not to be closed") } - fn casm_definition(&self, class_hash: ClassHash) -> Result>, StateError> { + fn casm_definition( + &self, + class_hash: ClassHash, + ) -> Result, StateError> { if let Some(casm_def) = decided::casm_definition(&self.decided_blocks, class_hash) { return Ok(Some(casm_def)); } @@ -142,7 +148,7 @@ impl StorageAdapter for ConcurrentStorageAdapter { fn class_definition_with_block_number( &self, class_hash: ClassHash, - ) -> Result, Vec)>, StateError> { + ) -> Result { if let Some(block_number_and_class_def) = decided::class_definition_with_block_number(&self.decided_blocks, class_hash) { @@ -161,7 +167,7 @@ impl StorageAdapter for ConcurrentStorageAdapter { &self, block_id: BlockId, class_hash: ClassHash, - ) -> Result>, StateError> { + ) -> Result, StateError> { if let Some(casm_def) = decided::casm_definition_at(&self.decided_blocks, block_id, class_hash) { @@ -405,6 +411,10 @@ mod decided { use std::collections::BTreeMap; use std::sync::RwLockReadGuard; + use pathfinder_common::class_definition::{ + SerializedCasmDefinition, + SerializedClassDefinition, + }; use pathfinder_common::state_update::ContractUpdate; use pathfinder_common::{ BlockId, @@ -460,7 +470,7 @@ mod decided { pub fn casm_definition( decided_blocks: &DecidedBlocks, class_hash: ClassHash, - ) -> Option> { + ) -> Option { let decided_blocks = decided_blocks.read().unwrap(); find_class(decided_blocks.values(), class_hash).map(|(_, c)| c.casm_def.clone()) } @@ -468,17 +478,17 @@ mod decided { pub fn class_definition_with_block_number( decided_blocks: &DecidedBlocks, class_hash: ClassHash, - ) -> Option<(Option, Vec)> { + ) -> Option<(Option, SerializedClassDefinition)> { let decided_blocks = decided_blocks.read().unwrap(); find_class(decided_blocks.values(), class_hash) - .map(|(b, c)| (Some(b), c.sierra_def.clone())) + .map(|(b, c)| (Some(b), c.sierra_def.clone().into())) } pub fn casm_definition_at( decided_blocks: &DecidedBlocks, block_id: BlockId, class_hash: ClassHash, - ) -> Option> { + ) -> Option { let guard = decided_blocks.read().unwrap(); let it = rev_blocks_by_id(&guard, block_id); find_class(it, class_hash).map(|(_, c)| c.casm_def.clone()) @@ -491,7 +501,7 @@ mod decided { ) -> ClassDefinitionAtWithBlockNumber { let guard = decided_blocks.read().unwrap(); let it = rev_blocks_by_id(&guard, block_id); - find_class(it, class_hash).map(|(b, c)| (b, c.sierra_def.clone())) + find_class(it, class_hash).map(|(b, c)| (b, c.sierra_def.clone().into())) } pub fn storage_value( @@ -563,6 +573,10 @@ mod decided { use std::collections::{BTreeMap, HashMap}; use std::sync::{Arc, RwLock}; + use pathfinder_common::class_definition::{ + SerializedCasmDefinition, + SerializedSierraDefinition, + }; use pathfinder_common::state_update::{ ContractClassUpdate, ContractUpdate, @@ -591,8 +605,8 @@ mod decided { declared_classes: vec![DeclaredClass { sierra_hash: SierraHash::ZERO, casm_hash_v2: CasmHash::ZERO, - sierra_def: vec![0], - casm_def: vec![1], + sierra_def: SerializedSierraDefinition::from_slice(&[0]), + casm_def: SerializedCasmDefinition::from_slice(&[1]), }], state_update: StateUpdateData { contract_updates: HashMap::from([ @@ -664,7 +678,10 @@ mod decided { #[test] fn success() { - assert_eq!(casm_definition(&two(), ClassHash::ZERO), Some(vec![1])); + assert_eq!( + casm_definition(&two(), ClassHash::ZERO), + Some(SerializedCasmDefinition::from_slice(&[1])) + ); } } @@ -685,7 +702,10 @@ mod decided { fn success() { assert_eq!( class_definition_with_block_number(&two(), ClassHash::ZERO), - Some((Some(BlockNumber::GENESIS), vec![0])) + Some(( + Some(BlockNumber::GENESIS), + SerializedClassDefinition::from_slice(&[0]) + )) ); } } @@ -712,7 +732,7 @@ mod decided { BlockId::Number(BlockNumber::GENESIS), ClassHash::ZERO, ), - Some(vec![1]) + Some(SerializedCasmDefinition::from_slice(&[1])) ); } @@ -726,7 +746,7 @@ mod decided { BlockId::Number(BlockNumber::GENESIS + 1), ClassHash::ZERO, ), - Some(vec![1]) + Some(SerializedCasmDefinition::from_slice(&[1])) ); } @@ -754,7 +774,7 @@ mod decided { fn latest_instant_match() { assert_eq!( casm_definition_at(&one(), BlockId::Latest, ClassHash::ZERO,), - Some(vec![1]) + Some(SerializedCasmDefinition::from_slice(&[1])) ); } @@ -762,7 +782,7 @@ mod decided { fn latest_skips_blocks_that_dont_match() { assert_eq!( casm_definition_at(&two(), BlockId::Latest, ClassHash::ZERO,), - Some(vec![1]) + Some(SerializedCasmDefinition::from_slice(&[1])) ); } } @@ -789,7 +809,10 @@ mod decided { BlockId::Number(BlockNumber::GENESIS), ClassHash::ZERO, ), - Some((BlockNumber::GENESIS, vec![0])) + Some(( + BlockNumber::GENESIS, + SerializedClassDefinition::from_slice(&[0]) + )) ); } @@ -803,7 +826,10 @@ mod decided { BlockId::Number(BlockNumber::GENESIS + 1), ClassHash::ZERO, ), - Some((BlockNumber::GENESIS, vec![0])) + Some(( + BlockNumber::GENESIS, + SerializedClassDefinition::from_slice(&[0]) + )) ); } @@ -831,7 +857,10 @@ mod decided { fn latest_instant_match() { assert_eq!( class_definition_at_with_block_number(&one(), BlockId::Latest, ClassHash::ZERO), - Some((BlockNumber::GENESIS, vec![0])) + Some(( + BlockNumber::GENESIS, + SerializedClassDefinition::from_slice(&[0]) + )) ); } @@ -839,7 +868,10 @@ mod decided { fn latest_skips_blocks_that_dont_match() { assert_eq!( class_definition_at_with_block_number(&two(), BlockId::Latest, ClassHash::ZERO), - Some((BlockNumber::GENESIS, vec![0])) + Some(( + BlockNumber::GENESIS, + SerializedClassDefinition::from_slice(&[0]) + )) ); } } diff --git a/crates/executor/src/state_reader/storage_adapter/rc.rs b/crates/executor/src/state_reader/storage_adapter/rc.rs index fb97925c26..e929e4070f 100644 --- a/crates/executor/src/state_reader/storage_adapter/rc.rs +++ b/crates/executor/src/state_reader/storage_adapter/rc.rs @@ -2,10 +2,16 @@ use std::rc::Rc; use blockifier::blockifier::config::TransactionExecutorConfig; use blockifier::state::errors::StateError; +use pathfinder_common::class_definition::SerializedCasmDefinition; use pathfinder_common::{BlockHash, BlockId}; use pathfinder_storage::Transaction; -use crate::state_reader::storage_adapter::{map_anyhow_to_state_err, StorageAdapter}; +use crate::state_reader::storage_adapter::{ + map_anyhow_to_state_err, + ClassDefinitionAtWithBlockNumber, + ClassDefinitionWithBlockNumber, + StorageAdapter, +}; #[derive(Clone)] pub struct RcStorageAdapter<'tx> { @@ -32,7 +38,7 @@ impl<'tx> StorageAdapter for RcStorageAdapter<'tx> { fn casm_definition( &self, class_hash: pathfinder_common::ClassHash, - ) -> Result>, StateError> { + ) -> Result, StateError> { self.db_tx .casm_definition(class_hash) .map_err(map_anyhow_to_state_err) @@ -41,7 +47,7 @@ impl<'tx> StorageAdapter for RcStorageAdapter<'tx> { fn class_definition_with_block_number( &self, class_hash: pathfinder_common::ClassHash, - ) -> Result, Vec)>, StateError> { + ) -> Result { self.db_tx .class_definition_with_block_number(class_hash) .map_err(map_anyhow_to_state_err) @@ -51,7 +57,7 @@ impl<'tx> StorageAdapter for RcStorageAdapter<'tx> { &self, block_id: BlockId, class_hash: pathfinder_common::ClassHash, - ) -> Result>, StateError> { + ) -> Result, StateError> { self.db_tx .casm_definition_at(block_id, class_hash) .map_err(map_anyhow_to_state_err) @@ -61,7 +67,7 @@ impl<'tx> StorageAdapter for RcStorageAdapter<'tx> { &self, block_id: BlockId, class_hash: pathfinder_common::ClassHash, - ) -> Result)>, StateError> { + ) -> Result { self.db_tx .class_definition_at_with_block_number(block_id, class_hash) .map_err(map_anyhow_to_state_err) diff --git a/crates/feeder-gateway/src/main.rs b/crates/feeder-gateway/src/main.rs index 26f19f9845..2e4a60ebc4 100644 --- a/crates/feeder-gateway/src/main.rs +++ b/crates/feeder-gateway/src/main.rs @@ -37,6 +37,7 @@ use pathfinder_block_commitments::{ calculate_receipt_commitment, calculate_transaction_commitment, }; +use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedClassDefinition}; use pathfinder_common::integration_testing::debug_create_port_marker_file; use pathfinder_common::prelude::*; use pathfinder_common::state_update::ContractClassUpdate; @@ -505,7 +506,7 @@ async fn serve(cli: Cli, storage_rx: Receiver>) -> anyh match class { Ok(class) => { - let response = warp::http::Response::builder().header("content-type", "application/json").body(class).unwrap(); + let response = warp::http::Response::builder().header("content-type", "application/json").body(class.into_bytes()).unwrap(); Result::<_, Infallible>::Ok(response) }, Err(_) => { @@ -546,7 +547,7 @@ async fn serve(cli: Cli, storage_rx: Receiver>) -> anyh match compiled_class { Ok(compiled_class) => { - let response = warp::http::Response::builder().header("content-type", "application/json").body(compiled_class).unwrap(); + let response = warp::http::Response::builder().header("content-type", "application/json").body(compiled_class.into_bytes()).unwrap(); Result::<_, Infallible>::Ok(response) }, Err(_) => { @@ -823,7 +824,7 @@ fn resolve_state_update( fn resolve_class( tx: &pathfinder_storage::Transaction<'_>, class_hash: ClassHash, -) -> anyhow::Result> { +) -> anyhow::Result { let definition = tx .class_definition(class_hash) .context("Reading class definition from database")? @@ -836,7 +837,7 @@ fn resolve_class( fn resolve_compiled_class( tx: &pathfinder_storage::Transaction<'_>, compiled_class_hash: ClassHash, -) -> anyhow::Result> { +) -> anyhow::Result { let definition = tx .casm_definition(compiled_class_hash) .context("Reading compiled class definition from database")? diff --git a/crates/gateway-client/src/lib.rs b/crates/gateway-client/src/lib.rs index e334785b1b..6b04dbcae0 100644 --- a/crates/gateway-client/src/lib.rs +++ b/crates/gateway-client/src/lib.rs @@ -5,6 +5,7 @@ use std::sync::{Arc, RwLock}; use std::time::Duration; use anyhow::Context; +use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedClassDefinition}; use pathfinder_common::prelude::*; use reqwest::Url; use starknet_gateway_types::error::SequencerError; @@ -72,7 +73,7 @@ pub trait GatewayApi: Sync { &self, class_hash: ClassHash, block: BlockId, - ) -> Result { + ) -> Result { unimplemented!(); } @@ -80,7 +81,7 @@ pub trait GatewayApi: Sync { &self, class_hash: ClassHash, block: BlockId, - ) -> Result { + ) -> Result { unimplemented!(); } @@ -175,7 +176,7 @@ impl GatewayApi for Arc { &self, class_hash: ClassHash, block: BlockId, - ) -> Result { + ) -> Result { self.as_ref().class_by_hash(class_hash, block).await } @@ -183,7 +184,7 @@ impl GatewayApi for Arc { &self, class_hash: ClassHash, block: BlockId, - ) -> Result { + ) -> Result { self.as_ref().casm_by_hash(class_hash, block).await } @@ -556,14 +557,16 @@ impl GatewayApi for Client { &self, class_hash: ClassHash, block: BlockId, - ) -> Result { - self.feeder_gateway_request() + ) -> Result { + let bytes = self + .feeder_gateway_request() .get_class_by_hash() .class_hash(class_hash) .block(block) .retry(self.retry) .get_as_bytes() - .await + .await?; + Ok(SerializedClassDefinition::from_bytes(bytes.to_vec())) } /// Gets CASM for a particular class hash. @@ -572,14 +575,16 @@ impl GatewayApi for Client { &self, class_hash: ClassHash, block: BlockId, - ) -> Result { - self.feeder_gateway_request() + ) -> Result { + let bytes = self + .feeder_gateway_request() .get_compiled_class_by_class_hash() .class_hash(class_hash) .block(block) .retry(self.retry) .get_as_bytes() - .await + .await?; + Ok(SerializedCasmDefinition::from_bytes(bytes.to_vec())) } /// Gets transaction status by transaction hash. diff --git a/crates/p2p/src/sync/client/conv.rs b/crates/p2p/src/sync/client/conv.rs index eda381860c..a5ea6d2a9f 100644 --- a/crates/p2p/src/sync/client/conv.rs +++ b/crates/p2p/src/sync/client/conv.rs @@ -25,6 +25,8 @@ use pathfinder_common::class_definition::{ Cairo, SelectorAndFunctionIndex, SelectorAndOffset, + SerializedCairoDefinition, + SerializedSierraDefinition, Sierra, }; use pathfinder_common::event::Event; @@ -885,10 +887,7 @@ impl TryFromDto for L1DataAvailabilit } } -#[derive(Debug)] -pub struct CairoDefinition(pub Vec); - -impl TryFromDto for CairoDefinition { +impl TryFromDto for SerializedCairoDefinition { fn try_from_dto(dto: p2p_proto::class::Cairo0Class) -> anyhow::Result { #[derive(Debug, Serialize)] struct SelectorAndOffset { @@ -955,13 +954,11 @@ impl TryFromDto for CairoDefinition { }; let class_def = serde_json::to_vec(&class_def).context("serialize cairo class definition")?; - Ok(Self(class_def)) + Ok(Self::from_bytes(class_def)) } } -pub struct SierraDefinition(pub Vec); - -impl TryFromDto for SierraDefinition { +impl TryFromDto for SerializedSierraDefinition { fn try_from_dto(dto: p2p_proto::class::Cairo1Class) -> anyhow::Result { #[derive(Debug, Serialize)] pub struct SelectorAndFunctionIndex { @@ -1020,7 +1017,7 @@ impl TryFromDto for SierraDefinition { let sierra = serde_json::to_vec(&sierra).context("serialize sierra class definition")?; - Ok(Self(sierra)) + Ok(Self::from_bytes(sierra)) } } diff --git a/crates/p2p/src/sync/client/peer_agnostic.rs b/crates/p2p/src/sync/client/peer_agnostic.rs index 060d2ec347..8a2023b998 100644 --- a/crates/p2p/src/sync/client/peer_agnostic.rs +++ b/crates/p2p/src/sync/client/peer_agnostic.rs @@ -26,6 +26,7 @@ use p2p_proto::sync::transaction::{ TransactionsRequest, TransactionsResponse, }; +use pathfinder_common::class_definition::{SerializedCairoDefinition, SerializedSierraDefinition}; use pathfinder_common::event::Event; use pathfinder_common::prelude::*; use pathfinder_common::state_update::{ContractClassUpdate, StateUpdateData}; @@ -50,7 +51,7 @@ use traits::{ }; use crate::peer_data::PeerData; -use crate::sync::client::conv::{CairoDefinition, FromDto, SierraDefinition, TryFromDto}; +use crate::sync::client::conv::{FromDto, TryFromDto}; use crate::sync::client::types::{ ClassDefinition, ClassDefinitionsError, @@ -461,12 +462,12 @@ impl BlockClient for Client { async fn class_definitions_for_block( self, - block: BlockNumber, + block_number: BlockNumber, declared_classes_count: u64, ) -> Result)>, ClassDefinitionsError> { let request = ClassesRequest { iteration: Iteration { - start: BlockNumberOrHash::Number(block.get()), + start: BlockNumberOrHash::Number(block_number.get()), direction: Direction::Forward, limit: 1, step: 1.into(), @@ -495,11 +496,11 @@ impl BlockClient for Client { domain: _, class_hash, })) => { - let definition = CairoDefinition::try_from_dto(class) + let definition = SerializedCairoDefinition::try_from_dto(class) .map_err(|_| ClassDefinitionsError::CairoDefinitionError(peer))?; class_definitions.push(ClassDefinition::Cairo { - block_number: block, - definition: definition.0, + block_number, + definition, hash: ClassHash(class_hash.0), }); } @@ -508,11 +509,11 @@ impl BlockClient for Client { domain: _, class_hash, })) => { - let definition = SierraDefinition::try_from_dto(class) + let sierra_definition = SerializedSierraDefinition::try_from_dto(class) .map_err(|_| ClassDefinitionsError::SierraDefinitionError(peer))?; class_definitions.push(ClassDefinition::Sierra { - block_number: block, - sierra_definition: definition.0, + block_number, + sierra_definition, hash: SierraHash(class_hash.0), }); } @@ -1261,7 +1262,7 @@ mod class_definition_stream { domain: _, class_hash, })) => { - let Ok(CairoDefinition(definition)) = CairoDefinition::try_from_dto(class) else { + let Ok(definition) = SerializedCairoDefinition::try_from_dto(class) else { // TODO punish the peer tracing::debug!(%peer, "Cairo definition failed to parse"); return None; @@ -1278,7 +1279,7 @@ mod class_definition_stream { domain: _, class_hash, })) => { - let Ok(SierraDefinition(definition)) = SierraDefinition::try_from_dto(class) else { + let Ok(sierra_definition) = SerializedSierraDefinition::try_from_dto(class) else { // TODO punish the peer tracing::debug!(%peer, "Sierra definition failed to parse"); return None; @@ -1286,7 +1287,7 @@ mod class_definition_stream { Some(ClassDefinition::Sierra { block_number, - sierra_definition: definition, + sierra_definition, hash: SierraHash(class_hash.0), }) } diff --git a/crates/p2p/src/sync/client/peer_agnostic/fixtures.rs b/crates/p2p/src/sync/client/peer_agnostic/fixtures.rs index f70148f8a6..df08ff8798 100644 --- a/crates/p2p/src/sync/client/peer_agnostic/fixtures.rs +++ b/crates/p2p/src/sync/client/peer_agnostic/fixtures.rs @@ -17,6 +17,7 @@ use p2p_proto::sync::state::{ StateDiffsResponse, }; use p2p_proto::sync::transaction::{TransactionWithReceipt, TransactionsResponse}; +use pathfinder_common::class_definition::{SerializedCairoDefinition, SerializedSierraDefinition}; use pathfinder_common::event::Event; use pathfinder_common::prelude::*; use pathfinder_common::state_update::{ContractClassUpdate, ContractUpdate, StateUpdateData}; @@ -33,7 +34,7 @@ use rand::seq::SliceRandom; use tokio::sync::Mutex; use super::ClassDefinition; -use crate::sync::client::conv::{CairoDefinition, SierraDefinition, ToDto, TryFromDto}; +use crate::sync::client::conv::{ToDto, TryFromDto}; use crate::sync::client::peer_agnostic::Receipt; #[derive(Clone, PartialEq, TaggedDebug)] @@ -352,7 +353,7 @@ pub fn class(tag: i32, block_number: u64) -> ClassDefinition { }) => { Tagged::get(format!("class {tag}"), || ClassDefinition::Cairo { block_number, - definition: CairoDefinition::try_from_dto(class).unwrap().0, + definition: SerializedCairoDefinition::try_from_dto(class).unwrap(), hash: ClassHash(class_hash.0), }) .unwrap() @@ -365,7 +366,7 @@ pub fn class(tag: i32, block_number: u64) -> ClassDefinition { }) => { Tagged::get(format!("class {tag}"), || ClassDefinition::Sierra { block_number, - sierra_definition: SierraDefinition::try_from_dto(class).unwrap().0, + sierra_definition: SerializedSierraDefinition::try_from_dto(class).unwrap(), hash: SierraHash(class_hash.0), }) .unwrap() diff --git a/crates/p2p/src/sync/client/types.rs b/crates/p2p/src/sync/client/types.rs index 0aea681134..c641ff0d92 100644 --- a/crates/p2p/src/sync/client/types.rs +++ b/crates/p2p/src/sync/client/types.rs @@ -1,6 +1,11 @@ use anyhow::Context; use fake::Dummy; use libp2p::PeerId; +use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedClassDefinition, + SerializedSierraDefinition, +}; use pathfinder_common::event::Event; use pathfinder_common::prelude::*; use pathfinder_common::receipt::{ExecutionResources, ExecutionStatus, L2ToL1Message}; @@ -14,24 +19,24 @@ use crate::sync::client::conv::TryFromDto; pub enum ClassDefinition { Cairo { block_number: BlockNumber, - definition: Vec, + definition: SerializedCairoDefinition, hash: ClassHash, }, Sierra { block_number: BlockNumber, - sierra_definition: Vec, + sierra_definition: SerializedSierraDefinition, hash: SierraHash, }, } impl ClassDefinition { /// Return Cairo or Sierra class definition depending on the variant. - pub fn class_definition(&self) -> Vec { + pub fn class_definition(&self) -> SerializedClassDefinition { match self { - Self::Cairo { definition, .. } => definition.clone(), + Self::Cairo { definition, .. } => definition.clone().into(), Self::Sierra { sierra_definition, .. - } => sierra_definition.clone(), + } => sierra_definition.clone().into(), } } } diff --git a/crates/pathfinder/examples/compute_class_hash.rs b/crates/pathfinder/examples/compute_class_hash.rs index 18d2948d31..a4e4e322ac 100644 --- a/crates/pathfinder/examples/compute_class_hash.rs +++ b/crates/pathfinder/examples/compute_class_hash.rs @@ -10,11 +10,10 @@ fn main() -> Result<(), Box> { } let mut s = Vec::new(); std::io::stdin().read_to_end(&mut s).unwrap(); - let s = s; - let class_hash = match pathfinder_class_hash::compute_class_hash(&s)? { - pathfinder_class_hash::ComputedClassHash::Cairo(h) => h.0, - pathfinder_class_hash::ComputedClassHash::Sierra(h) => h.0, - }; - println!("{class_hash:x}"); + let definition = + pathfinder_common::class_definition::SerializedClassDefinition::from_bytes(s); + let (hash, _) = pathfinder_class_hash::compute_class_hash(definition)?; + let class_hash = hash.hash(); + println!("{:x}", class_hash.0); Ok(()) } diff --git a/crates/pathfinder/examples/recompute_casm_class_hashes.rs b/crates/pathfinder/examples/recompute_casm_class_hashes.rs index 7810482bef..2f7384ac55 100644 --- a/crates/pathfinder/examples/recompute_casm_class_hashes.rs +++ b/crates/pathfinder/examples/recompute_casm_class_hashes.rs @@ -44,7 +44,10 @@ fn main() -> Result<(), Box> { let definition = zstd::decode_all(definition.as_slice()) .map_err(|e| rusqlite::types::FromSqlError::Other(e.into())) .unwrap(); - let computed_hash = pathfinder_compiler::casm_class_hash_v2(&definition).unwrap(); + let computed_hash = pathfinder_compiler::casm_class_hash_v2( + &pathfinder_common::class_definition::SerializedCasmDefinition::from_bytes(definition), + ) + .unwrap(); println!( "Computed CASM hash for class {:?}: {:x?}", class_hash, computed_hash.0 diff --git a/crates/pathfinder/src/bin/pathfinder/main.rs b/crates/pathfinder/src/bin/pathfinder/main.rs index 8a3261a567..2680f30bf8 100644 --- a/crates/pathfinder/src/bin/pathfinder/main.rs +++ b/crates/pathfinder/src/bin/pathfinder/main.rs @@ -552,10 +552,12 @@ fn compile_main(config: CompileConfig) -> anyhow::Result<()> { use std::io::{Read, Write}; const SIERRA_DEFINITION_SIZE_ESTIMATE: usize = 400 * 1024; // 400 KiB - let mut sierra_definition = Vec::with_capacity(SIERRA_DEFINITION_SIZE_ESTIMATE); + let mut sierra_bytes = Vec::with_capacity(SIERRA_DEFINITION_SIZE_ESTIMATE); std::io::stdin() - .read_to_end(&mut sierra_definition) + .read_to_end(&mut sierra_bytes) .context("reading Sierra from stdin")?; + let sierra_definition = + pathfinder_common::class_definition::SerializedSierraDefinition::from_bytes(sierra_bytes); let casm = pathfinder_compiler::compile_sierra_to_casm_impl( &sierra_definition, @@ -564,7 +566,7 @@ fn compile_main(config: CompileConfig) -> anyhow::Result<()> { .context("compiling Sierra to CASM")?; std::io::stdout() - .write_all(&casm) + .write_all(casm.as_bytes()) .context("writing CASM to stdout") } diff --git a/crates/pathfinder/src/devnet/class.rs b/crates/pathfinder/src/devnet/class.rs index b83f367edf..1e80ae5ce7 100644 --- a/crates/pathfinder/src/devnet/class.rs +++ b/crates/pathfinder/src/devnet/class.rs @@ -1,6 +1,10 @@ use pathfinder_class_hash::compute_sierra_class_hash; use pathfinder_class_hash::json::SierraContractDefinition; -use pathfinder_common::class_definition::Sierra; +use pathfinder_common::class_definition::{ + SerializedCasmDefinition, + SerializedSierraDefinition, + Sierra, +}; use pathfinder_common::{state_update, CasmHash, SierraHash}; use pathfinder_compiler::{ casm_class_hash_v2, @@ -57,11 +61,11 @@ pub struct PrepocessedSierra { // Deserialized into a format compatible with p2p, and hence the validator (for execution) pub cairo1_class_p2p: p2p_proto::class::Cairo1Class, // Re-serialized into a storage-compatible format - pub sierra_class_ser: Vec, + pub sierra_class_ser: SerializedSierraDefinition, // Casm hash v2 pub casm_hash_v2: CasmHash, // Casm - compiled from sierra - pub casm: Vec, + pub casm: SerializedCasmDefinition, } /// Preprocess a Sierra class definition. Class hash is computed if not @@ -101,7 +105,8 @@ pub fn preprocess_sierra( }; // Re-serialize into a storage-compatible format - let sierra_class_ser = serde_json::to_vec(&sierra_class_def).unwrap(); + let sierra_class_ser = + SerializedSierraDefinition::from_bytes(serde_json::to_vec(&sierra_class_def).unwrap()); let cairo1_class_p2p = sierra_def_to_p2p_cairo1(&sierra_class_def); let casm = compile_sierra_to_casm_deser( sierra_class_def, diff --git a/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs b/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs index 7665425d3b..fb79c280f0 100644 --- a/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs +++ b/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs @@ -19,7 +19,12 @@ use p2p_proto::sync::transaction::{ TransactionsRequest, TransactionsResponse, }; -use pathfinder_common::{class_definition, BlockHash, BlockNumber, SignedBlockHeader}; +use pathfinder_common::class_definition::{ + self, + SerializedCasmDefinition, + SerializedClassDefinition, +}; +use pathfinder_common::{BlockHash, BlockNumber, SignedBlockHeader}; use pathfinder_storage::{Storage, Transaction}; use tokio::sync::mpsc; @@ -146,8 +151,11 @@ fn get_header( #[derive(Debug, Clone)] enum ClassDefinition { - Cairo(Vec), - Sierra { sierra: Vec, _casm: Vec }, + Cairo(SerializedClassDefinition), + Sierra { + sierra: SerializedClassDefinition, + _casm: SerializedCasmDefinition, + }, } fn get_classes_for_block( @@ -166,7 +174,7 @@ fn get_classes_for_block( Ok(match casm_definition { Some(_casm) => ClassDefinition::Sierra { sierra: definition, - _casm: Vec::new(), // TODO casm + _casm: SerializedCasmDefinition::from_slice(&[]), // TODO casm }, None => ClassDefinition::Cairo(definition), }) @@ -184,7 +192,7 @@ fn get_classes_for_block( let class: Class = match class_definition { ClassDefinition::Cairo(definition) => { let cairo_class = - serde_json::from_slice::>(&definition)?; + serde_json::from_slice::>(definition.as_bytes())?; Class::Cairo0 { class: cairo_class.to_dto(), domain: 0, // TODO @@ -195,7 +203,8 @@ fn get_classes_for_block( sierra, _casm: _, // TODO } => { - let sierra_class = serde_json::from_slice::>(&sierra)?; + let sierra_class = + serde_json::from_slice::>(sierra.as_bytes())?; Class::Cairo1 { class: sierra_class.to_dto(), diff --git a/crates/pathfinder/src/p2p_network/sync/sync_handlers/tests.rs b/crates/pathfinder/src/p2p_network/sync/sync_handlers/tests.rs index 4d1e1adf2e..66b2b449bb 100644 --- a/crates/pathfinder/src/p2p_network/sync/sync_handlers/tests.rs +++ b/crates/pathfinder/src/p2p_network/sync/sync_handlers/tests.rs @@ -104,7 +104,7 @@ mod prop { use futures::channel::mpsc; use futures::StreamExt; - use p2p::sync::client::conv::{CairoDefinition, SierraDefinition, TryFromDto}; + use p2p::sync::client::conv::TryFromDto; use p2p::sync::client::types::Receipt; use p2p_proto::class::Class; use p2p_proto::common::BlockNumberOrHash; @@ -124,6 +124,10 @@ mod prop { TransactionsRequest, TransactionsResponse, }; + use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedSierraDefinition, + }; use pathfinder_common::event::Event; use pathfinder_common::prelude::*; use pathfinder_common::state_update::SystemContractUpdate; @@ -353,11 +357,10 @@ mod prop { responses.into_iter().for_each(|response| match response { ClassesResponse::Class(Class::Cairo0 { class, domain: _, class_hash: _ }) => { - actual_cairo.push(CairoDefinition::try_from_dto(class).unwrap().0); + actual_cairo.push(SerializedCairoDefinition::try_from_dto(class).unwrap()); }, ClassesResponse::Class(Class::Cairo1 { class, domain: _, class_hash: _ }) => { - let SierraDefinition(sierra) = SierraDefinition::try_from_dto(class).unwrap(); - actual_sierra.push(sierra); + actual_sierra.push(SerializedSierraDefinition::try_from_dto(class).unwrap()); }, _ => panic!("unexpected response"), }); diff --git a/crates/pathfinder/src/state/sync.rs b/crates/pathfinder/src/state/sync.rs index 6fa927a271..0413176da3 100644 --- a/crates/pathfinder/src/state/sync.rs +++ b/crates/pathfinder/src/state/sync.rs @@ -11,6 +11,11 @@ use std::time::Duration; use anyhow::Context; use pathfinder_block_commitments as block_hash; +use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedSierraDefinition, +}; use pathfinder_common::prelude::*; use pathfinder_common::state_update::StateUpdateData; use pathfinder_common::{ @@ -78,14 +83,14 @@ pub enum SyncEvent { Reorg(BlockNumber), /// A new unique L2 Cairo 0.x class was found. CairoClass { - definition: Vec, + definition: SerializedCairoDefinition, hash: ClassHash, }, /// A new unique L2 Cairo 1.x class was found. SierraClass { - sierra_definition: Vec, + sierra_definition: SerializedSierraDefinition, sierra_hash: SierraHash, - casm_definition: Vec, + casm_definition: SerializedCasmDefinition, casm_hash: CasmHash, casm_hash_v2: CasmHash, }, @@ -1629,6 +1634,12 @@ Blockchain history must include the reorg tail and its parent block to perform a mod tests { use std::sync::Arc; + use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedClassDefinition, + SerializedSierraDefinition, + }; use pathfinder_common::event::Event; use pathfinder_common::felt_bytes; use pathfinder_common::macro_prelude::*; @@ -2302,7 +2313,7 @@ mod tests { let (event_tx, event_rx) = tokio::sync::mpsc::channel(1); let class_hash = class_hash_bytes!(b"class hash"); - let expected_definition = b"cairo class definition".to_vec(); + let expected_definition = SerializedCairoDefinition::from_slice(b"cairo class definition"); event_tx .send(SyncEvent::CairoClass { @@ -2331,7 +2342,10 @@ mod tests { let tx = connection.transaction().unwrap(); let definition = tx.class_definition(class_hash).unwrap().unwrap(); - assert_eq!(definition, expected_definition); + assert_eq!( + definition, + SerializedClassDefinition::from(expected_definition) + ); } #[tokio::test(flavor = "multi_thread")] @@ -2346,13 +2360,14 @@ mod tests { let (event_tx, event_rx) = tokio::sync::mpsc::channel(1); let class_hash = felt_bytes!(b"class hash"); - let expected_definition = b"sierra class definition".to_vec(); + let expected_definition = + SerializedSierraDefinition::from_slice(b"sierra class definition"); event_tx .send(SyncEvent::SierraClass { sierra_definition: expected_definition.clone(), sierra_hash: SierraHash(class_hash), - casm_definition: b"casm definition".to_vec(), + casm_definition: SerializedCasmDefinition::from_slice(b"casm definition"), casm_hash: casm_hash_bytes!(b"casm hash"), casm_hash_v2: casm_hash_bytes!(b"casm hash blake"), }) @@ -2378,7 +2393,10 @@ mod tests { let tx = connection.transaction().unwrap(); let definition = tx.class_definition(ClassHash(class_hash)).unwrap().unwrap(); - assert_eq!(definition, expected_definition); + assert_eq!( + definition, + SerializedClassDefinition::from(expected_definition) + ); let casm_hash_v2 = tx.casm_hash_v2(ClassHash(class_hash)).unwrap().unwrap(); assert_eq!(casm_hash_v2, casm_hash_bytes!(b"casm hash blake")); @@ -3303,8 +3321,8 @@ Blockchain history must include the reorg tail and its parent block to perform a let reorg_regression_data = ReorgRegressionData::new(); let removed_class_hash = SierraHash(reorg_regression_data.removed_class_hash.0); - let sierra_definition = b"sierra definition".to_vec(); - let casm_definition = b"casm definition".to_vec(); + let sierra_definition = SerializedSierraDefinition::from_slice(b"sierra definition"); + let casm_definition = SerializedCasmDefinition::from_slice(b"casm definition"); let casm_hash = casm_hash_bytes!(b"casm hash"); let casm_hash_v2 = casm_hash_bytes!(b"casm hash blake"); diff --git a/crates/pathfinder/src/state/sync/class.rs b/crates/pathfinder/src/state/sync/class.rs index 47aa2c4911..7c4aa05711 100644 --- a/crates/pathfinder/src/state/sync/class.rs +++ b/crates/pathfinder/src/state/sync/class.rs @@ -1,16 +1,22 @@ use anyhow::Context; +use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedClass, + SerializedSierraDefinition, +}; use pathfinder_common::{CasmHash, ClassHash, SierraHash}; use starknet_gateway_client::{BlockId, GatewayApi}; pub enum DownloadedClass { Cairo { - definition: Vec, + definition: SerializedCairoDefinition, hash: ClassHash, }, Sierra { - sierra_definition: Vec, + sierra_definition: SerializedSierraDefinition, sierra_hash: SierraHash, - casm_definition: Vec, + casm_definition: SerializedCasmDefinition, casm_hash_v2: CasmHash, }, } @@ -27,27 +33,25 @@ pub async fn download_class( let definition = sequencer .class_by_hash(class_hash, BlockId::Latest) .await - .with_context(|| format!("Downloading class {}", class_hash.0))? - .to_vec(); + .with_context(|| format!("Downloading class {}", class_hash.0))?; let (tx, rx) = tokio::sync::oneshot::channel(); rayon::spawn(move || { - let computed_hash = compute_class_hash(&definition).context("Computing class hash"); - let _ = tx.send((computed_hash, definition)); + let result = compute_class_hash(definition).context("Computing class hash"); + let _ = tx.send(result); }); - let (hash, definition) = rx.await.context("Panic on rayon thread")?; - let hash = hash?; + let (hash, serialized_class) = rx.await.context("Panic on rayon thread")??; use pathfinder_class_hash::ComputedClassHash; - match hash { - ComputedClassHash::Cairo(hash) => { + match (hash, serialized_class) { + (ComputedClassHash::Cairo(hash), SerializedClass::Cairo(definition)) => { if class_hash != hash { tracing::warn!(expected=%class_hash, computed=%hash, "Cairo 0 class hash mismatch"); } Ok(DownloadedClass::Cairo { definition, hash }) } - ComputedClassHash::Sierra(hash) => { + (ComputedClassHash::Sierra(hash), SerializedClass::Sierra(sierra_definition)) => { anyhow::ensure!( class_hash == hash, "Class hash mismatch, {} instead of {}", @@ -66,24 +70,23 @@ pub async fn download_class( let (sierra_definition, casm_definition) = if fetch_casm_from_fgw { ( - definition, + sierra_definition, sequencer .casm_by_hash(class_hash, BlockId::Latest) .await - .with_context(|| format!("Downloading CASM {}", class_hash.0))? - .to_vec(), + .with_context(|| format!("Downloading CASM {}", class_hash.0))?, ) } else { let (send, recv) = tokio::sync::oneshot::channel(); rayon::spawn(move || { let _span = span.entered(); let compile_result = pathfinder_compiler::compile_sierra_to_casm( - &definition, + &sierra_definition, compiler_resource_limit, blockifier_libfuncs, ) .context("Compiling Sierra class"); - let _ = send.send((compile_result, definition)); + let _ = send.send((compile_result, sierra_definition)); }); let (casm_definition, sierra_definition) = recv.await.expect("Panic on rayon thread"); @@ -96,7 +99,6 @@ pub async fn download_class( .casm_by_hash(class_hash, BlockId::Latest) .await .with_context(|| format!("Downloading CASM {}", class_hash.0))? - .to_vec() } }; (sierra_definition, casm_definition) @@ -131,5 +133,6 @@ pub async fn download_class( casm_hash_v2, }) } + _ => unreachable!("compute_class_hash returns matching hash and class variants"), } } diff --git a/crates/pathfinder/src/state/sync/l2.rs b/crates/pathfinder/src/state/sync/l2.rs index 14b4f6bccf..1673d585d2 100644 --- a/crates/pathfinder/src/state/sync/l2.rs +++ b/crates/pathfinder/src/state/sync/l2.rs @@ -1603,6 +1603,7 @@ mod tests { use std::sync::LazyLock; use assert_matches::assert_matches; + use pathfinder_common::class_definition::SerializedClassDefinition; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_common::Chain; @@ -1854,12 +1855,18 @@ mod tests { }) } - static CONTRACT0_DEF: LazyLock = - LazyLock::new(|| format!("{DEF0}0{DEF1}").into()); - static CONTRACT0_DEF_V2: LazyLock = - LazyLock::new(|| format!("{DEF0}0 v2{DEF1}").into()); - static CONTRACT1_DEF: LazyLock = - LazyLock::new(|| format!("{DEF0}1{DEF1}").into()); + static CONTRACT0_DEF: LazyLock = + LazyLock::new(|| { + SerializedClassDefinition::from_bytes(format!("{DEF0}0{DEF1}").into_bytes()) + }); + static CONTRACT0_DEF_V2: LazyLock = + LazyLock::new(|| { + SerializedClassDefinition::from_bytes(format!("{DEF0}0 v2{DEF1}").into_bytes()) + }); + static CONTRACT1_DEF: LazyLock = + LazyLock::new(|| { + SerializedClassDefinition::from_bytes(format!("{DEF0}1{DEF1}").into_bytes()) + }); static BLOCK0: LazyLock = LazyLock::new(|| reply::Block { block_hash: BLOCK0_HASH, @@ -2135,7 +2142,7 @@ mod tests { mock: &mut MockGatewayApi, seq: &mut mockall::Sequence, class_hash: ClassHash, - returned_result: Result, + returned_result: Result, ) { mock.expect_class_by_hash() .withf(move |x, _| x == &class_hash) @@ -2148,7 +2155,7 @@ mod tests { fn expect_class_by_hash_no_sequence( mock: &mut MockGatewayApi, class_hash: ClassHash, - returned_result: Result, + returned_result: Result, ) { mock.expect_class_by_hash() .withf(move |x, _| x == &class_hash) @@ -2159,7 +2166,7 @@ mod tests { fn expect_class_by_hash_no_sequence_at_most_once( mock: &mut MockGatewayApi, class_hash: ClassHash, - returned_result: Result, + returned_result: Result, ) { mock.expect_class_by_hash() .withf(move |x, _| x == &class_hash) diff --git a/crates/pathfinder/src/state/sync/repair.rs b/crates/pathfinder/src/state/sync/repair.rs index 0a5d8f2833..53350b67d6 100644 --- a/crates/pathfinder/src/state/sync/repair.rs +++ b/crates/pathfinder/src/state/sync/repair.rs @@ -153,6 +153,10 @@ fn store_repaired_class( mod tests { use std::collections::HashSet; + use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedClassDefinition, + }; use pathfinder_common::state_update::StateUpdateData; use pathfinder_common::BlockNumber; use pathfinder_storage::StorageBuilder; @@ -192,7 +196,7 @@ mod tests { async fn cairo_repair() { let storage = storage(); let hash = ClassHash(pathfinder_crypto::Felt::from_hex_str("0xdeadbeef").unwrap()); - let definition = b"cairo class definition bytes".to_vec(); + let definition = SerializedCairoDefinition::from_slice(b"cairo class definition bytes"); insert_placeholder(&storage, hash); @@ -214,7 +218,7 @@ mod tests { let mut db = storage.connection().unwrap(); let tx = db.transaction().unwrap(); let stored = tx.class_definition(hash).unwrap(); - assert_eq!(stored, Some(definition)); + assert_eq!(stored, Some(SerializedClassDefinition::from(definition))); } /// Cairo 0 classes can have a mismatch between the declared hash and the @@ -225,7 +229,7 @@ mod tests { let storage = storage(); let declared = ClassHash(pathfinder_crypto::Felt::from_hex_str("0xaaaa").unwrap()); let computed = ClassHash(pathfinder_crypto::Felt::from_hex_str("0xbbbb").unwrap()); - let definition = b"cairo class definition bytes".to_vec(); + let definition = SerializedCairoDefinition::from_slice(b"cairo class definition bytes"); insert_placeholder(&storage, declared); @@ -248,7 +252,10 @@ mod tests { let mut db = storage.connection().unwrap(); let tx = db.transaction().unwrap(); // Stored under the declared hash, not the computed one. - assert_eq!(tx.class_definition(declared).unwrap(), Some(definition)); + assert_eq!( + tx.class_definition(declared).unwrap(), + Some(SerializedClassDefinition::from(definition)) + ); assert_eq!(tx.class_definition(computed).unwrap(), None); } @@ -258,7 +265,7 @@ mod tests { let storage = storage(); let good = ClassHash(pathfinder_crypto::Felt::from_hex_str("0x1111").unwrap()); let bad = ClassHash(pathfinder_crypto::Felt::from_hex_str("0x2222").unwrap()); - let definition = b"good class definition".to_vec(); + let definition = SerializedCairoDefinition::from_slice(b"good class definition"); // Insert both in one state update to avoid block number conflicts. { @@ -292,7 +299,10 @@ mod tests { let mut db = storage.connection().unwrap(); let tx = db.transaction().unwrap(); - assert_eq!(tx.class_definition(good).unwrap(), Some(definition)); + assert_eq!( + tx.class_definition(good).unwrap(), + Some(SerializedClassDefinition::from(definition)) + ); // bad was not repaired — definition IS NULL, so it still appears in // the missing list. let still_missing = tx.class_hashes_with_missing_definitions().unwrap(); diff --git a/crates/pathfinder/src/sync.rs b/crates/pathfinder/src/sync.rs index 8bcaa576b8..5360557bca 100644 --- a/crates/pathfinder/src/sync.rs +++ b/crates/pathfinder/src/sync.rs @@ -318,6 +318,12 @@ mod tests { calculate_transaction_commitment, compute_final_hash, }; + use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedClassDefinition, + SerializedSierraDefinition, + }; use pathfinder_common::event::Event; use pathfinder_common::prelude::*; use pathfinder_common::receipt::Receipt; @@ -613,7 +619,11 @@ mod tests { ); pretty_assertions_sorted::assert_eq!( cairo_defs, - expected.cairo_defs.into_iter().collect::>(), + expected + .cairo_defs + .into_iter() + .map(|(h, d)| (h, SerializedClassDefinition::from(d))) + .collect::>(), "block {}", block_number ); @@ -623,7 +633,15 @@ mod tests { .sierra_defs .into_iter() // All sierra fixtures are not compile-able - .map(|(h, s, _, _)| (h, (s, starknet_gateway_test_fixtures::class_definitions::CAIRO_1_1_0_BALANCE_CASM_JSON.to_vec()))) + .map(|(h, s, _, _)| ( + h, + ( + SerializedClassDefinition::from(s), + SerializedCasmDefinition::from_slice( + starknet_gateway_test_fixtures::class_definitions::CAIRO_1_1_0_BALANCE_CASM_JSON + ), + ) + )) .collect::>(), "block {}", block_number @@ -1073,8 +1091,8 @@ mod tests { &self, _: ClassHash, _: BlockId, - ) -> Result { - Ok(bytes::Bytes::from_static( + ) -> Result { + Ok(SerializedCasmDefinition::from_slice( starknet_gateway_test_fixtures::class_definitions::CAIRO_1_1_0_BALANCE_CASM_JSON, )) } diff --git a/crates/pathfinder/src/sync/checkpoint.rs b/crates/pathfinder/src/sync/checkpoint.rs index 2f99e17541..b3e9a55ca3 100644 --- a/crates/pathfinder/src/sync/checkpoint.rs +++ b/crates/pathfinder/src/sync/checkpoint.rs @@ -1370,6 +1370,12 @@ mod tests { use fake::{Dummy, Fake, Faker}; use futures::{stream, SinkExt}; use p2p::libp2p::PeerId; + use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedClassDefinition, + SerializedSierraDefinition, + }; use pathfinder_common::event::Event; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; @@ -1402,8 +1408,8 @@ mod tests { &self, _: ClassHash, _: BlockId, - ) -> Result { - Ok(bytes::Bytes::from_static(CASM2)) + ) -> Result { + Ok(SerializedCasmDefinition::from_slice(CASM2)) } } @@ -1441,7 +1447,7 @@ mod tests { struct Setup { pub streamed_classes: Vec, anyhow::Error>>, pub declared_classes: DeclaredClasses, - pub expected_defs: HashMap>, + pub expected_defs: HashMap, pub storage: Storage, } @@ -1477,19 +1483,20 @@ mod tests { fake_block(1, state_update1), ]; - blocks[1].cairo_defs = vec![(cairo_hash, CAIRO.to_vec())]; + blocks[1].cairo_defs = + vec![(cairo_hash, SerializedCairoDefinition::from_slice(CAIRO))]; blocks[1].sierra_defs = vec![ // Does not compile ( sierra0_hash, - SIERRA0.to_vec(), + SerializedSierraDefinition::from_slice(SIERRA0), Default::default(), Default::default(), ), // Compiles just fine ( sierra2_hash, - SIERRA2.to_vec(), + SerializedSierraDefinition::from_slice(SIERRA2), Default::default(), Default::default(), ), @@ -1498,17 +1505,17 @@ mod tests { let streamed_classes = vec![ Ok(PeerData::for_tests(ClassDefinition::Cairo { block_number: BlockNumber::GENESIS + 1, - definition: CAIRO.to_vec(), + definition: SerializedCairoDefinition::from_slice(CAIRO), hash: cairo_hash, })), Ok(PeerData::for_tests(ClassDefinition::Sierra { block_number: BlockNumber::GENESIS + 1, - sierra_definition: SIERRA0.to_vec(), + sierra_definition: SerializedSierraDefinition::from_slice(SIERRA0), hash: sierra0_hash, })), Ok(PeerData::for_tests(ClassDefinition::Sierra { block_number: BlockNumber::GENESIS + 1, - sierra_definition: SIERRA2.to_vec(), + sierra_definition: SerializedSierraDefinition::from_slice(SIERRA2), hash: sierra2_hash, })), ]; @@ -1529,9 +1536,15 @@ mod tests { ]); let expected_defs = [ - (cairo_hash, CAIRO.to_vec()), - (ClassHash(sierra0_hash.0), SIERRA0.to_vec()), - (ClassHash(sierra2_hash.0), SIERRA2.to_vec()), + (cairo_hash, SerializedClassDefinition::from_slice(CAIRO)), + ( + ClassHash(sierra0_hash.0), + SerializedClassDefinition::from_slice(SIERRA0), + ), + ( + ClassHash(sierra2_hash.0), + SerializedClassDefinition::from_slice(SIERRA2), + ), ] .into(); @@ -1576,12 +1589,13 @@ mod tests { db.casm_definition(ClassHash(SIERRA0_HASH.0)) .unwrap() .unwrap(), - CASM2 + SerializedCasmDefinition::from_slice(CASM2) ); assert!(serde_json::from_slice::( - &db.casm_definition(ClassHash(SIERRA2_HASH.0)) + db.casm_definition(ClassHash(SIERRA2_HASH.0)) .unwrap() .unwrap() + .as_bytes() ) .unwrap()["compiler_version"] .is_string()); diff --git a/crates/pathfinder/src/sync/class_definitions.rs b/crates/pathfinder/src/sync/class_definitions.rs index 494c1fa44a..962ee8335f 100644 --- a/crates/pathfinder/src/sync/class_definitions.rs +++ b/crates/pathfinder/src/sync/class_definitions.rs @@ -10,7 +10,14 @@ use p2p::sync::client::types::ClassDefinition as P2PClassDefinition; use p2p::PeerData; use p2p_proto::transaction; use pathfinder_class_hash::from_parts::{compute_cairo_class_hash, compute_sierra_class_hash}; -use pathfinder_common::class_definition::{Cairo, ClassDefinition as GwClassDefinition, Sierra}; +use pathfinder_common::class_definition::{ + Cairo, + ClassDefinition as GwClassDefinition, + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedSierraDefinition, + Sierra, +}; use pathfinder_common::state_update::DeclaredClasses; use pathfinder_common::{BlockNumber, CasmHash, ClassHash, SierraHash}; use pathfinder_storage::{Storage, Transaction}; @@ -37,8 +44,8 @@ pub struct ClassWithLayout { #[derive(Debug)] pub(super) enum ClassDefinition { - Cairo(Vec), - Sierra(Vec), + Cairo(SerializedCairoDefinition), + Sierra(SerializedSierraDefinition), } #[derive(Debug)] @@ -57,10 +64,10 @@ pub struct CompiledClass { #[derive(Debug)] pub enum CompiledClassDefinition { - Cairo(Vec), + Cairo(SerializedCairoDefinition), Sierra { - sierra_definition: Vec, - casm_definition: Vec, + sierra_definition: SerializedSierraDefinition, + casm_definition: SerializedCasmDefinition, casm_hash_v2: CasmHash, }, } @@ -143,7 +150,7 @@ fn verify_layout_impl( hash, } => { let layout = GwClassDefinition::Cairo( - serde_json::from_slice::>(&definition).map_err(|error| { + serde_json::from_slice::>(definition.as_bytes()).map_err(|error| { tracing::debug!(%peer, %block_number, %error, "Bad class layout"); SyncError::BadClassLayout(*peer) })?, @@ -161,10 +168,12 @@ fn verify_layout_impl( hash, } => { let layout = GwClassDefinition::Sierra( - serde_json::from_slice::>(&sierra_definition).map_err(|error| { - tracing::debug!(%peer, %block_number, %error, "Bad class layout"); - SyncError::BadClassLayout(*peer) - })?, + serde_json::from_slice::>(sierra_definition.as_bytes()).map_err( + |error| { + tracing::debug!(%peer, %block_number, %error, "Bad class layout"); + SyncError::BadClassLayout(*peer) + }, + )?, ); Ok(ClassWithLayout { block_number, @@ -523,8 +532,7 @@ fn compile_or_fetch_impl( .map_err(|error| { tracing::debug!(%block_number, class_hash=%hash, %error, "Fetching casm from feeder gateway failed"); SyncError::FetchingCasmFailed - })? - .to_vec(), + })?, }; let casm_hash_v2 = pathfinder_casm_hashes::get_precomputed_casm_v2_hash(&hash); diff --git a/crates/rpc/src/executor.rs b/crates/rpc/src/executor.rs index b09062e455..a30fb129df 100644 --- a/crates/rpc/src/executor.rs +++ b/crates/rpc/src/executor.rs @@ -1,4 +1,5 @@ use anyhow::Context; +use pathfinder_common::class_definition::{SerializedClassDefinition, SerializedSierraDefinition}; use pathfinder_common::transaction::TransactionVariant; use pathfinder_common::{BlockNumber, ChainId, StarknetVersion}; use pathfinder_executor::types::to_starknet_api_transaction; @@ -91,8 +92,9 @@ pub(crate) fn map_broadcasted_transaction( .serialize_to_json() .context("Serializing Cairo class to JSON")?; - let contract_class = - pathfinder_executor::parse_deprecated_class_definition(contract_class_json)?; + let contract_class = pathfinder_executor::parse_deprecated_class_definition( + SerializedClassDefinition::from_bytes(contract_class_json), + )?; Some(ClassInfo::new( &contract_class, @@ -107,8 +109,9 @@ pub(crate) fn map_broadcasted_transaction( .serialize_to_json() .context("Serializing Cairo class to JSON")?; - let contract_class = - pathfinder_executor::parse_deprecated_class_definition(contract_class_json)?; + let contract_class = pathfinder_executor::parse_deprecated_class_definition( + SerializedClassDefinition::from_bytes(contract_class_json), + )?; Some(ClassInfo::new( &contract_class, @@ -120,8 +123,9 @@ pub(crate) fn map_broadcasted_transaction( BroadcastedTransaction::Declare(BroadcastedDeclareTransaction::V2(tx)) => { let sierra_version = SierraVersion::extract_from_program(&tx.contract_class.sierra_program)?; - let sierra_definition = serde_json::to_vec(&tx.contract_class) - .context("Serializing Sierra class definition")?; + let sierra_definition = + SerializedSierraDefinition::from_bytes(serde_json::to_vec(&tx.contract_class) + .context("Serializing Sierra class definition")?); let casm_contract_definition = pathfinder_compiler::compile_sierra_to_casm( &sierra_definition, compiler_resource_limits, @@ -144,8 +148,9 @@ pub(crate) fn map_broadcasted_transaction( BroadcastedTransaction::Declare(BroadcastedDeclareTransaction::V3(tx)) => { let sierra_version = SierraVersion::extract_from_program(&tx.contract_class.sierra_program)?; - let sierra_definition = serde_json::to_vec(&tx.contract_class) - .context("Serializing Sierra class definition")?; + let sierra_definition = + SerializedSierraDefinition::from_bytes(serde_json::to_vec(&tx.contract_class) + .context("Serializing Sierra class definition")?); let casm_contract_definition = pathfinder_compiler::compile_sierra_to_casm( &sierra_definition, compiler_resource_limits, @@ -282,7 +287,7 @@ pub fn compose_executor_transaction( .class_definition(tx.class_hash)? .context("Fetching class definition")?; let class_definition: crate::types::class::sierra::SierraContractClass = - serde_json::from_str(&String::from_utf8(class_definition)?) + serde_json::from_slice(class_definition.as_bytes()) .context("Deserializing class definition")?; let sierra_version = SierraVersion::extract_from_program(&class_definition.sierra_program)?; @@ -304,7 +309,7 @@ pub fn compose_executor_transaction( .class_definition(tx.class_hash)? .context("Fetching class definition")?; let class_definition: crate::types::class::sierra::SierraContractClass = - serde_json::from_str(&String::from_utf8(class_definition)?) + serde_json::from_str(&String::from_utf8(class_definition.into_bytes())?) .context("Deserializing class definition")?; let sierra_version = SierraVersion::extract_from_program(&class_definition.sierra_program)?; diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs index acf3523318..85f2669b34 100644 --- a/crates/rpc/src/lib.rs +++ b/crates/rpc/src/lib.rs @@ -283,6 +283,11 @@ impl crate::dto::DeserializeForVersion for SubscriptionId { pub mod test_utils { use std::collections::HashMap; + use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedSierraDefinition, + }; use pathfinder_common::event::Event; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; @@ -398,11 +403,13 @@ pub mod test_utils { let contract1_update2 = HashMap::from([(storage_addr, storage_value_bytes!(b"storage value 2"))]); - let class0_definition = - starknet_gateway_test_fixtures::class_definitions::CONTRACT_DEFINITION.to_vec(); + let class0_definition = SerializedCairoDefinition::from_slice( + starknet_gateway_test_fixtures::class_definitions::CONTRACT_DEFINITION, + ); let class1_definition = &class0_definition; - let sierra_class_definition = - starknet_gateway_test_fixtures::class_definitions::CAIRO_0_11_SIERRA.to_vec(); + let sierra_class_definition = SerializedSierraDefinition::from_slice( + starknet_gateway_test_fixtures::class_definitions::CAIRO_0_11_SIERRA, + ); db_txn .insert_cairo_class_definition(class0_hash, &class0_definition) @@ -414,7 +421,7 @@ pub mod test_utils { .insert_sierra_class_definition( &sierra_class, &sierra_class_definition, - &[], + &SerializedCasmDefinition::from_slice(&[]), &sierra_casm_hash_v2, ) .unwrap(); @@ -913,13 +920,21 @@ pub mod test_utils { starknet_gateway_test_fixtures::class_definitions::CONTRACT_DEFINITION; for cairo in state_update_copy.declared_cairo_classes { - tx.insert_cairo_class_definition(cairo, class_definition) - .unwrap(); + tx.insert_cairo_class_definition( + cairo, + &SerializedCairoDefinition::from_slice(class_definition), + ) + .unwrap(); } for (sierra, casm) in state_update_copy.declared_sierra_classes { - tx.insert_sierra_class_definition(&sierra, b"sierra def", b"casm def", &casm) - .unwrap(); + tx.insert_sierra_class_definition( + &sierra, + &SerializedSierraDefinition::from_slice(b"sierra def"), + &SerializedCasmDefinition::from_slice(b"casm def"), + &casm, + ) + .unwrap(); } tx.commit().unwrap(); @@ -1269,21 +1284,37 @@ pub mod test_utils { starknet_gateway_test_fixtures::class_definitions::CONTRACT_DEFINITION; for cairo in pre_latest_state_update.declared_cairo_classes { - tx.insert_cairo_class_definition(cairo, class_definition) - .unwrap(); + tx.insert_cairo_class_definition( + cairo, + &SerializedCairoDefinition::from_slice(class_definition), + ) + .unwrap(); } for (sierra, casm) in pre_latest_state_update.declared_sierra_classes { - tx.insert_sierra_class_definition(&sierra, b"sierra def", b"casm def", &casm) - .unwrap(); + tx.insert_sierra_class_definition( + &sierra, + &SerializedSierraDefinition::from_slice(b"sierra def"), + &SerializedCasmDefinition::from_slice(b"casm def"), + &casm, + ) + .unwrap(); } for cairo in pre_confirmed_state_update_copy.declared_cairo_classes { - tx.insert_cairo_class_definition(cairo, class_definition) - .unwrap(); + tx.insert_cairo_class_definition( + cairo, + &SerializedCairoDefinition::from_slice(class_definition), + ) + .unwrap(); } for (sierra, casm) in pre_confirmed_state_update_copy.declared_sierra_classes { - tx.insert_sierra_class_definition(&sierra, b"sierra def", b"casm def", &casm) - .unwrap(); + tx.insert_sierra_class_definition( + &sierra, + &SerializedSierraDefinition::from_slice(b"sierra def"), + &SerializedCasmDefinition::from_slice(b"casm def"), + &casm, + ) + .unwrap(); } tx.commit().unwrap(); diff --git a/crates/rpc/src/method/add_declare_transaction.rs b/crates/rpc/src/method/add_declare_transaction.rs index 47f2ba9133..5d58b0b737 100644 --- a/crates/rpc/src/method/add_declare_transaction.rs +++ b/crates/rpc/src/method/add_declare_transaction.rs @@ -464,6 +464,7 @@ impl crate::dto::SerializeForVersion for Output { mod tests { use std::sync::LazyLock; + use pathfinder_common::class_definition::SerializedClassDefinition; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_common::transaction::{DataAvailabilityMode, ResourceBound, ResourceBounds}; @@ -485,7 +486,7 @@ mod tests { use crate::types::ContractClass; pub static CONTRACT_CLASS: LazyLock = LazyLock::new(|| { - ContractClass::from_definition_bytes(CONTRACT_DEFINITION) + ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(CONTRACT_DEFINITION)) .unwrap() .as_cairo() .unwrap() @@ -502,25 +503,25 @@ mod tests { .get_mut("prime") .unwrap() = serde_json::json!("0x1"); let definition = serde_json::to_vec(&definition).unwrap(); - ContractClass::from_definition_bytes(&definition) + ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(&definition)) .unwrap() .as_cairo() .unwrap() }); pub static SIERRA_CLASS: LazyLock = LazyLock::new(|| { - ContractClass::from_definition_bytes(CAIRO_2_0_0_STACK_OVERFLOW) + ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(CAIRO_2_0_0_STACK_OVERFLOW)) .unwrap() .as_sierra() .unwrap() }); pub static INTEGRATION_SIERRA_CLASS: LazyLock = LazyLock::new(|| { - ContractClass::from_definition_bytes(include_bytes!( + ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(include_bytes!( "../../fixtures/contracts/\ integration_class_0x5ae9d09292a50ed48c5930904c880dab56e85b825022a7d689cfc9e65e01ee7.\ json" - )) + ))) .unwrap() .as_sierra() .unwrap() diff --git a/crates/rpc/src/method/call.rs b/crates/rpc/src/method/call.rs index bd40a3da4b..186eb2a8a1 100644 --- a/crates/rpc/src/method/call.rs +++ b/crates/rpc/src/method/call.rs @@ -256,6 +256,11 @@ mod tests { mod in_memory { use assert_matches::assert_matches; + use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedSierraDefinition, + }; use pathfinder_common::felt; use pathfinder_common::prelude::*; use starknet_gateway_test_fixtures::class_definitions::{ @@ -292,8 +297,11 @@ mod tests { let block1_number = BlockNumber::GENESIS + 1; let block1_hash = BlockHash(felt!("0xb01")); - tx.insert_cairo_class_definition(CONTRACT_DEFINITION_CLASS_HASH, CONTRACT_DEFINITION) - .unwrap(); + tx.insert_cairo_class_definition( + CONTRACT_DEFINITION_CLASS_HASH, + &SerializedCairoDefinition::from_slice(CONTRACT_DEFINITION), + ) + .unwrap(); let header = BlockHeader::builder() .number(block1_number) @@ -435,8 +443,8 @@ mod tests { let tx = connection.transaction().unwrap(); tx.insert_sierra_class_definition( &sierra_hash, - sierra_definition, - casm_definition, + &SerializedSierraDefinition::from_slice(sierra_definition), + &SerializedCasmDefinition::from_slice(casm_definition), &casm_hash_v2, ) .unwrap(); @@ -541,8 +549,8 @@ mod tests { tx.insert_sierra_class_definition( &sierra_hash, - sierra_definition, - casm_definition, + &SerializedSierraDefinition::from_slice(sierra_definition), + &SerializedCasmDefinition::from_slice(casm_definition), &casm_hash_v2, ) .unwrap(); @@ -701,15 +709,15 @@ mod tests { tx.insert_sierra_class_definition( &sierra_hash, - sierra_definition, - casm_definition, + &SerializedSierraDefinition::from_slice(sierra_definition), + &SerializedCasmDefinition::from_slice(casm_definition), &casm_hash_v2, ) .unwrap(); tx.insert_sierra_class_definition( &caller_sierra_hash, - &caller_sierra_definition, - caller_casm_definition, + &SerializedSierraDefinition::from_bytes(caller_sierra_definition), + &SerializedCasmDefinition::from_slice(caller_casm_definition), &caller_casm_hash_v2, ) .unwrap(); diff --git a/crates/rpc/src/method/estimate_fee.rs b/crates/rpc/src/method/estimate_fee.rs index 601a60d87d..1a4039641f 100644 --- a/crates/rpc/src/method/estimate_fee.rs +++ b/crates/rpc/src/method/estimate_fee.rs @@ -232,6 +232,7 @@ impl crate::dto::SerializeForVersion for Output { #[cfg(test)] mod tests { use assert_matches::assert_matches; + use pathfinder_common::class_definition::SerializedClassDefinition; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_common::transaction::{DataAvailabilityMode, ResourceBound, ResourceBounds}; @@ -266,7 +267,7 @@ mod tests { casm_hash!("0x069032ff71f77284e1a0864a573007108ca5cc08089416af50f03260f5d6d4d8"); let contract_class: SierraContractClass = - ContractClass::from_definition_bytes(sierra_definition) + ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(sierra_definition)) .unwrap() .as_sierra() .unwrap(); @@ -605,7 +606,7 @@ mod tests { casm_hash!("0x02F58B23F7D98FF076AE59C08125AAFFD6DECCF1A7E97378D1A303B1A4223989"); let contract_class: SierraContractClass = - ContractClass::from_definition_bytes(sierra_definition) + ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(sierra_definition)) .unwrap() .as_sierra() .unwrap(); @@ -641,7 +642,7 @@ mod tests { casm_hash!("0x138cd11c6de707426665bd8b0425d7411bb8dc5cbee15867025007a933b3379"); let contract_class: SierraContractClass = - ContractClass::from_definition_bytes(sierra_definition) + ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(sierra_definition)) .unwrap() .as_sierra() .unwrap(); diff --git a/crates/rpc/src/method/estimate_message_fee.rs b/crates/rpc/src/method/estimate_message_fee.rs index 774b618a97..9e3bb15e55 100644 --- a/crates/rpc/src/method/estimate_message_fee.rs +++ b/crates/rpc/src/method/estimate_message_fee.rs @@ -269,6 +269,10 @@ impl From for ApplicationError { #[cfg(test)] mod tests { use assert_matches::assert_matches; + use pathfinder_common::class_definition::{ + SerializedCasmDefinition, + SerializedSierraDefinition, + }; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_common::L1DataAvailabilityMode; @@ -309,8 +313,8 @@ mod tests { class_hash!("0x032908a85d43275f8509ba5f2acae88811b293463a3521dc05ab06d534b40848"); tx.insert_sierra_class_definition( &SierraHash(class_hash.0), - sierra_json, - casm_json, + &SerializedSierraDefinition::from_slice(sierra_json), + &SerializedCasmDefinition::from_slice(casm_json), &casm_hash_bytes!(b"casm hash blake"), ) .expect("insert class"); diff --git a/crates/rpc/src/method/get_class.rs b/crates/rpc/src/method/get_class.rs index c71596fe7e..2a5179e2f0 100644 --- a/crates/rpc/src/method/get_class.rs +++ b/crates/rpc/src/method/get_class.rs @@ -85,7 +85,7 @@ pub async fn get_class( return Err(Error::ClassHashNotFound); }; - let class = ContractClass::from_definition_bytes(&definition) + let class = ContractClass::try_from_serialized_definition(&definition) .context("Parsing class definition")? .into(); diff --git a/crates/rpc/src/method/get_class_at.rs b/crates/rpc/src/method/get_class_at.rs index 7b84e5a99d..b20d1d6e52 100644 --- a/crates/rpc/src/method/get_class_at.rs +++ b/crates/rpc/src/method/get_class_at.rs @@ -98,7 +98,7 @@ pub async fn get_class_at( .context("Fetching class definition")? .context("Class definition missing from database")?; - let class = ContractClass::from_definition_bytes(&definition) + let class = ContractClass::try_from_serialized_definition(&definition) .context("Parsing class definition")?; Ok(class) diff --git a/crates/rpc/src/method/get_compiled_casm.rs b/crates/rpc/src/method/get_compiled_casm.rs index d93a0dca5d..6791d1646e 100644 --- a/crates/rpc/src/method/get_compiled_casm.rs +++ b/crates/rpc/src/method/get_compiled_casm.rs @@ -90,13 +90,11 @@ pub async fn get_compiled_casm(context: RpcContext, input: Input) -> Result BroadcastedTransaction { let contract_class = - crate::types::ContractClass::from_definition_bytes(SIERRA_DEFINITION) + crate::types::ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(SIERRA_DEFINITION)) .unwrap() .as_sierra() .unwrap(); @@ -955,7 +956,7 @@ pub(crate) mod tests { let contract_definition = include_bytes!("../../fixtures/contracts/libfuncs_coverage.json"); let contract_class = - crate::types::ContractClass::from_definition_bytes(contract_definition) + crate::types::ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(contract_definition)) .unwrap() .as_sierra() .unwrap(); diff --git a/crates/rpc/src/method/trace_block_transactions.rs b/crates/rpc/src/method/trace_block_transactions.rs index d505ebb941..071a5dffaf 100644 --- a/crates/rpc/src/method/trace_block_transactions.rs +++ b/crates/rpc/src/method/trace_block_transactions.rs @@ -823,6 +823,10 @@ impl From for TraceBlockTransactionsError { #[cfg(test)] pub(crate) mod tests { use assert_matches::assert_matches; + use pathfinder_common::class_definition::{ + SerializedCasmDefinition, + SerializedSierraDefinition, + }; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_common::receipt::Receipt; @@ -874,8 +878,8 @@ pub(crate) mod tests { tx.insert_sierra_class_definition( &SierraHash(fixtures::SIERRA_HASH.0), - fixtures::SIERRA_DEFINITION, - fixtures::CASM_DEFINITION, + &SerializedSierraDefinition::from_slice(fixtures::SIERRA_DEFINITION), + &SerializedCasmDefinition::from_slice(fixtures::CASM_DEFINITION), &casm_hash_bytes!(b"casm hash blake"), )?; @@ -1216,8 +1220,8 @@ pub(crate) mod tests { tx.insert_sierra_class_definition( &SierraHash(fixtures::SIERRA_HASH.0), - fixtures::SIERRA_DEFINITION, - fixtures::CASM_DEFINITION, + &SerializedSierraDefinition::from_slice(fixtures::SIERRA_DEFINITION), + &SerializedCasmDefinition::from_slice(fixtures::CASM_DEFINITION), &casm_hash_bytes!(b"casm hash blake"), )?; @@ -1362,8 +1366,8 @@ pub(crate) mod tests { tx.insert_sierra_class_definition( &SierraHash(fixtures::SIERRA_HASH.0), - fixtures::SIERRA_DEFINITION, - fixtures::CASM_DEFINITION, + &SerializedSierraDefinition::from_slice(fixtures::SIERRA_DEFINITION), + &SerializedCasmDefinition::from_slice(fixtures::CASM_DEFINITION), &casm_hash_bytes!(b"casm hash blake"), )?; diff --git a/crates/rpc/src/test_setup.rs b/crates/rpc/src/test_setup.rs index 644922c031..f91d19046c 100644 --- a/crates/rpc/src/test_setup.rs +++ b/crates/rpc/src/test_setup.rs @@ -1,3 +1,8 @@ +use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedSierraDefinition, +}; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_storage::Storage; @@ -42,8 +47,8 @@ pub async fn test_storage StateUpdate>( casm_hash!("0x0224b815fab6827eb21993e02e45e532e5476af6536dcf1f7085989ba9dc5bf0"); tx.insert_sierra_class_definition( &openzeppelin_account_sierra_hash, - openzeppelin_account_class_definition, - openzeppelin_account_casm_definition, + &SerializedSierraDefinition::from_slice(openzeppelin_account_class_definition), + &SerializedCasmDefinition::from_slice(openzeppelin_account_casm_definition), &casm_hash_bytes!(b"casm hash blake"), ) .unwrap(); @@ -53,16 +58,22 @@ pub async fn test_storage StateUpdate>( include_bytes!("../fixtures/contracts/universal_deployer.json"); let universal_deployer_class_hash = class_hash!("0x06f38fb91ddbf325a0625533576bb6f6eafd9341868a9ec3faa4b01ce6c4f4dc"); - tx.insert_cairo_class_definition(universal_deployer_class_hash, universal_deployer_definition) - .unwrap(); + tx.insert_cairo_class_definition( + universal_deployer_class_hash, + &SerializedCairoDefinition::from_slice(universal_deployer_definition), + ) + .unwrap(); // Declare ERC20 fee token contract class let erc20_class_hash = starknet_gateway_test_fixtures::class_definitions::ERC20_CONTRACT_DEFINITION_CLASS_HASH; let erc20_class_definition = starknet_gateway_test_fixtures::class_definitions::ERC20_CONTRACT_DEFINITION; - tx.insert_cairo_class_definition(erc20_class_hash, erc20_class_definition) - .unwrap(); + tx.insert_cairo_class_definition( + erc20_class_hash, + &SerializedCairoDefinition::from_slice(erc20_class_definition), + ) + .unwrap(); let header = BlockHeader::child_builder(&genesis) .timestamp(BlockTimestamp::new_or_panic(1)) diff --git a/crates/rpc/src/types/class.rs b/crates/rpc/src/types/class.rs index 3f07676e36..dc5833cd18 100644 --- a/crates/rpc/src/types/class.rs +++ b/crates/rpc/src/types/class.rs @@ -1,5 +1,6 @@ use anyhow::Context; use base64::prelude::*; +use pathfinder_common::class_definition::SerializedClassDefinition; #[derive(Clone, Debug, PartialEq, Eq)] pub enum ContractClass { @@ -19,8 +20,11 @@ impl ContractClass { /// /// Note that this function does not validate the class definition in any /// way, so this is only ever to be called for trusted data from storage. - pub fn from_definition_bytes(data: &[u8]) -> anyhow::Result { - let mut json = serde_json::from_slice::(data).context("Parsing json")?; + pub fn try_from_serialized_definition( + serialized_definition: &SerializedClassDefinition, + ) -> anyhow::Result { + let mut json = serde_json::from_slice::(serialized_definition.as_bytes()) + .context("Parsing json")?; let json_obj = json .as_object_mut() .context("Class definition is not a json object")?; @@ -228,8 +232,11 @@ pub mod cairo { impl CairoContractClass { pub fn class_hash(&self) -> anyhow::Result { let serialized = self.serialize_to_json()?; + let definition = pathfinder_common::class_definition::SerializedClassDefinition::from_bytes(serialized); - compute_class_hash(&serialized).context("Compute class hash") + compute_class_hash(definition) + .map(|(hash, _)| hash) + .context("Compute class hash") } pub fn serialize_to_json(&self) -> anyhow::Result> { @@ -687,7 +694,8 @@ pub mod sierra { impl SierraContractClass { pub fn class_hash(&self) -> anyhow::Result { let definition = serde_json::to_vec(self)?; - compute_class_hash(&definition) + let definition = pathfinder_common::class_definition::SerializedClassDefinition::from_bytes(definition); + compute_class_hash(definition).map(|(hash, _)| hash) } } @@ -779,6 +787,7 @@ mod tests { mod declare_class_hash { use pathfinder_class_hash::compute_class_hash; + use pathfinder_common::class_definition::SerializedClassDefinition; use starknet_gateway_test_fixtures::class_definitions::{ CAIRO_0_11_SIERRA, CONTRACT_DEFINITION, @@ -788,22 +797,33 @@ mod tests { #[test] fn compute_sierra_class_hash() { - let class_hash = compute_class_hash(CAIRO_0_11_SIERRA).unwrap(); + let (class_hash, _) = + compute_class_hash(SerializedClassDefinition::from_slice(CAIRO_0_11_SIERRA)) + .unwrap(); - let class = ContractClass::from_definition_bytes(CAIRO_0_11_SIERRA).unwrap(); + let class = ContractClass::try_from_serialized_definition( + &SerializedClassDefinition::from_slice(CAIRO_0_11_SIERRA), + ) + .unwrap(); assert_eq!(class.class_hash().unwrap(), class_hash); } #[test] fn compute_cairo_class_hash() { - let class_hash = compute_class_hash(CONTRACT_DEFINITION).unwrap(); + let (class_hash, _) = + compute_class_hash(SerializedClassDefinition::from_slice(CONTRACT_DEFINITION)) + .unwrap(); - let class = ContractClass::from_definition_bytes(CONTRACT_DEFINITION).unwrap(); + let class = ContractClass::try_from_serialized_definition( + &SerializedClassDefinition::from_slice(CONTRACT_DEFINITION), + ) + .unwrap(); assert_eq!(class.class_hash().unwrap(), class_hash); } } mod contract_class_serialization { + use pathfinder_common::class_definition::SerializedClassDefinition; use pathfinder_executor::parse_deprecated_class_definition; use super::super::cairo::CairoContractClass; @@ -830,14 +850,17 @@ mod tests { let serialized_definition = contract_class.serialize_to_json().unwrap(); - parse_deprecated_class_definition(serialized_definition).unwrap(); + parse_deprecated_class_definition(SerializedClassDefinition::from_bytes( + serialized_definition, + )) + .unwrap(); } #[test] fn parse_deprecated_class_definition_with_debug_info() { let definition = include_bytes!("../../fixtures/contracts/cairo0_open_zeppelin_class.json"); - let class = ContractClass::from_definition_bytes(definition).unwrap(); + let class = ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(definition)).unwrap(); // this step involves parsing the full program including debug info class.as_cairo().unwrap().serialize_to_json().unwrap(); diff --git a/crates/storage/src/connection/block.rs b/crates/storage/src/connection/block.rs index 57f157ddab..c124cd8622 100644 --- a/crates/storage/src/connection/block.rs +++ b/crates/storage/src/connection/block.rs @@ -649,6 +649,7 @@ fn parse_row_as_header(row: &rusqlite::Row<'_>) -> rusqlite::Result #[cfg(test)] mod tests { + use pathfinder_common::class_definition::SerializedCairoDefinition; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_common::L1DataAvailabilityMode; @@ -793,7 +794,8 @@ mod tests { // Add a class to test that purging a block unsets its block number; let cairo_hash = class_hash!("0x1234"); - tx.insert_cairo_class_definition(cairo_hash, &[]).unwrap(); + tx.insert_cairo_class_definition(cairo_hash, &SerializedCairoDefinition::from_slice(&[])) + .unwrap(); tx.insert_state_update( latest.number, &StateUpdate::default().with_declared_cairo_class(cairo_hash), diff --git a/crates/storage/src/connection/class.rs b/crates/storage/src/connection/class.rs index 47a3008231..cacda2df4f 100644 --- a/crates/storage/src/connection/class.rs +++ b/crates/storage/src/connection/class.rs @@ -1,4 +1,10 @@ use anyhow::Context; +use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedClassDefinition, + SerializedSierraDefinition, +}; use pathfinder_common::{ BlockId, BlockNumber, @@ -14,17 +20,17 @@ impl Transaction<'_> { pub fn insert_sierra_class_definition( &self, sierra_hash: &SierraHash, - sierra_definition: &[u8], - casm_definition: &[u8], + sierra_definition: &SerializedSierraDefinition, + casm_definition: &SerializedCasmDefinition, // Blake2 hash of the compiled class definition casm_hash_v2: &CasmHash, ) -> anyhow::Result<()> { let mut compressor = zstd::bulk::Compressor::new(10).context("Creating zstd compressor")?; - let sierra_definition = compressor - .compress(sierra_definition) + let compressed_sierra_definition = compressor + .compress(sierra_definition.as_bytes()) .context("Compressing sierra definition")?; - let casm_definition = compressor - .compress(casm_definition) + let compressed_casm_definition = compressor + .compress(casm_definition.as_bytes()) .context("Compressing casm definition")?; self.inner() @@ -32,7 +38,7 @@ impl Transaction<'_> { "INSERT INTO class_definitions (hash, definition) VALUES (?, ?) ON CONFLICT(hash) DO UPDATE SET definition = excluded.definition WHERE class_definitions.definition IS NULL", - params![sierra_hash, &sierra_definition], + params![sierra_hash, &compressed_sierra_definition], ) .context("Inserting sierra definition")?; @@ -45,7 +51,7 @@ impl Transaction<'_> { ", named_params! { ":hash": sierra_hash, - ":definition": &casm_definition, + ":definition": &compressed_casm_definition, }, ) .context("Inserting CASM definition")?; @@ -70,23 +76,23 @@ impl Transaction<'_> { pub fn update_sierra_class_definition( &self, sierra_hash: &SierraHash, - sierra_definition: &[u8], - casm_definition: &[u8], + sierra_definition: &SerializedSierraDefinition, + casm_definition: &SerializedCasmDefinition, casm_hash_v2: &CasmHash, ) -> anyhow::Result<()> { let mut compressor = zstd::bulk::Compressor::new(10).context("Creating zstd compressor")?; - let sierra_definition = compressor - .compress(sierra_definition) + let compressed_sierra_definition = compressor + .compress(sierra_definition.as_bytes()) .context("Compressing sierra definition")?; - let casm_definition = compressor - .compress(casm_definition) + let compressed_casm_definition = compressor + .compress(casm_definition.as_bytes()) .context("Compressing casm definition")?; self.inner() .execute( r"UPDATE class_definitions SET definition=:definition WHERE hash=:hash", named_params! { - ":definition": &sierra_definition, + ":definition": &compressed_sierra_definition, ":hash": sierra_hash }, ) @@ -96,7 +102,7 @@ impl Transaction<'_> { .execute( r"INSERT OR REPLACE INTO casm_definitions(hash, definition) VALUES(:hash, :definition)", named_params! { - ":definition": &casm_definition, + ":definition": &compressed_casm_definition, ":hash": sierra_hash, }, ) @@ -118,11 +124,11 @@ impl Transaction<'_> { pub fn insert_cairo_class_definition( &self, cairo_hash: ClassHash, - definition: &[u8], + definition: &SerializedCairoDefinition, ) -> anyhow::Result<()> { let mut compressor = zstd::bulk::Compressor::new(10).context("Creating zstd compressor")?; - let definition = compressor - .compress(definition) + let compressed_definition = compressor + .compress(definition.as_bytes()) .context("Compressing cairo definition")?; self.inner() @@ -130,7 +136,7 @@ impl Transaction<'_> { r"INSERT INTO class_definitions (hash, definition) VALUES (?, ?) ON CONFLICT(hash) DO UPDATE SET definition = excluded.definition WHERE class_definitions.definition IS NULL", - params![&cairo_hash, &definition], + params![&cairo_hash, &compressed_definition], ) .context("Inserting cairo definition")?; @@ -140,17 +146,17 @@ impl Transaction<'_> { pub fn update_cairo_class_definition( &self, cairo_hash: ClassHash, - definition: &[u8], + definition: &SerializedCairoDefinition, ) -> anyhow::Result<()> { let mut compressor = zstd::bulk::Compressor::new(10).context("Creating zstd compressor")?; - let definition = compressor - .compress(definition) + let compressed_definition = compressor + .compress(definition.as_bytes()) .context("Compressing cairo definition")?; self.inner() .execute( r"UPDATE class_definitions SET definition=? WHERE hash=?", - params![&definition, &cairo_hash], + params![&compressed_definition, &cairo_hash], ) .context("Updating cairo definition")?; @@ -174,7 +180,10 @@ impl Transaction<'_> { } /// Returns the uncompressed class definition. - pub fn class_definition(&self, class_hash: ClassHash) -> anyhow::Result>> { + pub fn class_definition( + &self, + class_hash: ClassHash, + ) -> anyhow::Result> { self.class_definition_with_block_number(class_hash) .map(|option| option.map(|(_block_number, definition)| definition)) } @@ -184,7 +193,7 @@ impl Transaction<'_> { pub fn class_definition_with_block_number( &self, class_hash: ClassHash, - ) -> anyhow::Result, Vec)>> { + ) -> anyhow::Result, SerializedClassDefinition)>> { let from_row = |row: &rusqlite::Row<'_>| { let definition = row.get_blob(0).map(|x| x.to_vec())?; let block_number = row.get_optional_block_number(1)?; @@ -206,7 +215,10 @@ impl Transaction<'_> { let definition = zstd::decode_all(definition.as_slice()).context("Decompressing class definition")?; - Ok(Some((block_number, definition))) + Ok(Some(( + block_number, + SerializedClassDefinition::from_bytes(definition), + ))) } fn compressed_class_definition_at_with_block_number( @@ -260,9 +272,9 @@ impl Transaction<'_> { &self, block_id: BlockId, class_hash: ClassHash, - ) -> anyhow::Result>> { + ) -> anyhow::Result> { self.class_definition_at_with_block_number(block_id, class_hash) - .map(|option| option.map(|(_block_number, definition)| definition)) + .map(|option| option.map(|(_, definition)| definition)) } /// Returns the uncompressed class definition if it has been declared at @@ -271,7 +283,7 @@ impl Transaction<'_> { &self, block_id: BlockId, class_hash: ClassHash, - ) -> anyhow::Result)>> { + ) -> anyhow::Result> { let definition = self.compressed_class_definition_at_with_block_number(block_id, class_hash)?; let Some((block_number, definition)) = definition else { @@ -279,12 +291,16 @@ impl Transaction<'_> { }; let definition = zstd::decode_all(definition.as_slice()).context("Decompressing class definition")?; + let definition = SerializedClassDefinition::from_bytes(definition); Ok(Some((block_number, definition))) } /// Returns the uncompressed compiled class definition. - pub fn casm_definition(&self, class_hash: ClassHash) -> anyhow::Result>> { + pub fn casm_definition( + &self, + class_hash: ClassHash, + ) -> anyhow::Result> { // Don't reuse the "_with_block_number" impl here since the suffixed one // requires a join that this one doesn't. let mut stmt = self @@ -303,7 +319,7 @@ impl Transaction<'_> { let definition = zstd::decode_all(definition.as_slice()) .context("Decompressing compiled class definition")?; - Ok(Some(definition)) + Ok(Some(SerializedCasmDefinition::from_bytes(definition))) } /// Returns the uncompressed compiled class definition, as well as the block @@ -311,7 +327,7 @@ impl Transaction<'_> { pub fn casm_definition_with_block_number( &self, class_hash: ClassHash, - ) -> anyhow::Result, Vec)>> { + ) -> anyhow::Result, SerializedCasmDefinition)>> { let from_row = |row: &rusqlite::Row<'_>| { let definition = row.get_blob(0).map(|x| x.to_vec())?; let block_number = row.get_optional_block_number(1)?; @@ -342,7 +358,10 @@ impl Transaction<'_> { let definition = zstd::decode_all(definition.as_slice()) .context("Decompressing compiled class definition")?; - Ok(Some((block_number, definition))) + Ok(Some(( + block_number, + SerializedCasmDefinition::from_bytes(definition), + ))) } /// Returns the uncompressed compiled class definition if it has been @@ -351,9 +370,9 @@ impl Transaction<'_> { &self, block_id: BlockId, class_hash: ClassHash, - ) -> anyhow::Result>> { + ) -> anyhow::Result> { self.casm_definition_at_with_block_number(block_id, class_hash) - .map(|option| option.map(|(_block_number, definition)| definition)) + .map(|option| option.map(|(_, definition)| definition)) } /// Returns the uncompressed compiled class definition if it has been @@ -363,14 +382,14 @@ impl Transaction<'_> { &self, block_id: BlockId, class_hash: ClassHash, - ) -> anyhow::Result, Vec)>> { + ) -> anyhow::Result, SerializedCasmDefinition)>> { let from_row = |row: &rusqlite::Row<'_>| { - let definition = row.get_blob(0).map(|x| x.to_vec())?; + let compressed_definition = row.get_blob(0).map(|x| x.to_vec())?; let block_number = row.get_optional_block_number(1)?; - Ok((block_number, definition)) + Ok((block_number, compressed_definition)) }; - let definition = match block_id { + let compressed_definition = match block_id { BlockId::Latest => { let mut stmt = self.inner().prepare_cached( r"SELECT @@ -421,13 +440,16 @@ impl Transaction<'_> { .optional() .context("Querying for compiled class definition")?; - let Some((block_number, definition)) = definition else { + let Some((block_number, compressed_definition)) = compressed_definition else { return Ok(None); }; - let definition = zstd::decode_all(definition.as_slice()) + let definition = zstd::decode_all(compressed_definition.as_slice()) .context("Decompressing compiled class definition")?; - Ok(Some((block_number, definition))) + Ok(Some(( + block_number, + SerializedCasmDefinition::from_bytes(definition), + ))) } /// Returns the compiled class hash for a class. @@ -617,10 +639,14 @@ mod tests { insert_placeholder(&tx, hash); let definition = b"example cairo program"; - tx.insert_cairo_class_definition(hash, definition).unwrap(); + tx.insert_cairo_class_definition(hash, &SerializedCairoDefinition::from_slice(definition)) + .unwrap(); let result = tx.class_definition(hash).unwrap(); - assert_eq!(result, Some(definition.to_vec())); + assert_eq!( + result, + Some(SerializedClassDefinition::from_slice(definition)) + ); } #[test] @@ -641,17 +667,23 @@ mod tests { tx.insert_sierra_class_definition( &sierra_hash, - sierra_definition, - casm_definition, + &SerializedSierraDefinition::from_slice(sierra_definition), + &SerializedCasmDefinition::from_slice(casm_definition), &casm_hash_v2, ) .unwrap(); let result = tx.class_definition(class_hash).unwrap(); - assert_eq!(result, Some(sierra_definition.to_vec())); + assert_eq!( + result, + Some(SerializedClassDefinition::from_slice(sierra_definition)) + ); let result = tx.casm_definition(class_hash).unwrap(); - assert_eq!(result, Some(casm_definition.to_vec())); + assert_eq!( + result, + Some(SerializedCasmDefinition::from_slice(casm_definition)) + ); } #[test] @@ -666,13 +698,22 @@ mod tests { let definition_a = b"definition A"; let definition_b = b"definition B"; - tx.insert_cairo_class_definition(hash, definition_a) - .unwrap(); - tx.insert_cairo_class_definition(hash, definition_b) - .unwrap(); + tx.insert_cairo_class_definition( + hash, + &SerializedCairoDefinition::from_slice(definition_a), + ) + .unwrap(); + tx.insert_cairo_class_definition( + hash, + &SerializedCairoDefinition::from_slice(definition_b), + ) + .unwrap(); let result = tx.class_definition(hash).unwrap(); - assert_eq!(result, Some(definition_a.to_vec())); + assert_eq!( + result, + Some(SerializedClassDefinition::from_slice(definition_a)) + ); } fn setup_class(transaction: &Transaction<'_>) -> (ClassHash, &'static [u8], serde_json::Value) { @@ -681,7 +722,7 @@ mod tests { let definition = br#"{"abi":{"see":"above"},"program":{"huge":"hash"},"entry_points_by_type":{"this might be a":"hash"}}"#; transaction - .insert_cairo_class_definition(hash, definition) + .insert_cairo_class_definition(hash, &SerializedCairoDefinition::from_slice(definition)) .unwrap(); ( @@ -720,12 +761,18 @@ mod tests { let cairo_hash = class_hash_bytes!(b"cairo hash"); let cairo_definition = b"example cairo program"; - tx.insert_cairo_class_definition(cairo_hash, cairo_definition) - .unwrap(); + tx.insert_cairo_class_definition( + cairo_hash, + &SerializedCairoDefinition::from_slice(cairo_definition), + ) + .unwrap(); let definition = tx.class_definition(cairo_hash).unwrap().unwrap(); - assert_eq!(definition, cairo_definition); + assert_eq!( + definition, + SerializedClassDefinition::from_slice(cairo_definition) + ); } #[test] @@ -743,8 +790,8 @@ mod tests { tx.insert_sierra_class_definition( &sierra_hash, - sierra_definition, - casm_definition, + &SerializedSierraDefinition::from_slice(sierra_definition), + &SerializedCasmDefinition::from_slice(casm_definition), &casm_hash_v2, ) .unwrap(); @@ -753,13 +800,19 @@ mod tests { .casm_definition(ClassHash(sierra_hash.0)) .unwrap() .unwrap(); - assert_eq!(definition, casm_definition); + assert_eq!( + definition, + SerializedCasmDefinition::from_slice(casm_definition) + ); let definition = tx .class_definition(ClassHash(sierra_hash.0)) .unwrap() .unwrap(); - assert_eq!(definition, sierra_definition); + assert_eq!( + definition, + SerializedClassDefinition::from_slice(sierra_definition) + ); let retrieved_casm_hash_v2 = tx.casm_hash_v2(ClassHash(sierra_hash.0)).unwrap().unwrap(); assert_eq!(retrieved_casm_hash_v2, casm_hash_v2); diff --git a/crates/storage/src/connection/state_update.rs b/crates/storage/src/connection/state_update.rs index 0b94def871..8389fcaf72 100644 --- a/crates/storage/src/connection/state_update.rs +++ b/crates/storage/src/connection/state_update.rs @@ -1075,6 +1075,11 @@ impl Transaction<'_> { #[cfg(test)] mod tests { + use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedSierraDefinition, + }; use pathfinder_common::macro_prelude::*; use pathfinder_common::BlockHeader; @@ -1103,7 +1108,8 @@ mod tests { let state_update = StateUpdate::default().with_declared_cairo_class(target_class); - tx.insert_cairo_class_definition(target_class, &[]).unwrap(); + tx.insert_cairo_class_definition(target_class, &SerializedCairoDefinition::from_slice(&[])) + .unwrap(); tx.insert_block_header(&header_0).unwrap(); tx.insert_block_header(&header_1).unwrap(); tx.insert_state_update(header_0.number, &state_update) @@ -1157,10 +1163,16 @@ mod tests { let diff_3 = StateUpdate::default(); let diff_4 = StateUpdate::default(); - tx.insert_cairo_class_definition(original_class, definition) - .unwrap(); - tx.insert_cairo_class_definition(replaced_class, definition) - .unwrap(); + tx.insert_cairo_class_definition( + original_class, + &SerializedCairoDefinition::from_slice(definition), + ) + .unwrap(); + tx.insert_cairo_class_definition( + replaced_class, + &SerializedCairoDefinition::from_slice(definition), + ) + .unwrap(); tx.insert_block_header(&header_0).unwrap(); tx.insert_block_header(&header_1).unwrap(); @@ -1242,15 +1254,21 @@ mod tests { // Submit the class definitions since this occurs out of band of the header and // state diff. - tx.insert_cairo_class_definition(CAIRO_HASH, b"cairo definition") - .unwrap(); - tx.insert_cairo_class_definition(CAIRO_HASH2, b"cairo definition 2") - .unwrap(); + tx.insert_cairo_class_definition( + CAIRO_HASH, + &SerializedCairoDefinition::from_slice(b"cairo definition"), + ) + .unwrap(); + tx.insert_cairo_class_definition( + CAIRO_HASH2, + &SerializedCairoDefinition::from_slice(b"cairo definition 2"), + ) + .unwrap(); tx.insert_sierra_class_definition( &SIERRA_HASH, - b"sierra definition", - b"casm definition", + &SerializedSierraDefinition::from_slice(b"sierra definition"), + &SerializedCasmDefinition::from_slice(b"casm definition"), &CASM_HASH_V2, ) .unwrap(); @@ -1323,7 +1341,10 @@ mod tests { .casm_definition_at(BlockId::Latest, ClassHash(SIERRA_HASH.0)) .unwrap() .unwrap(); - assert_eq!(definition, b"casm definition"); + assert_eq!( + definition, + SerializedCasmDefinition::from_slice(b"casm definition") + ); // non-existent state update let non_existent = tx.state_update((header.number + 1).into()).unwrap(); diff --git a/crates/storage/src/fake.rs b/crates/storage/src/fake.rs index 145e3cce15..27bdd15fd5 100644 --- a/crates/storage/src/fake.rs +++ b/crates/storage/src/fake.rs @@ -4,6 +4,12 @@ use std::ops::RangeInclusive; use fake::{Fake, Faker}; use pathfinder_class_hash::compute_class_hash; +use pathfinder_common::class_definition::{ + SerializedCairoDefinition, + SerializedCasmDefinition, + SerializedClassDefinition, + SerializedSierraDefinition, +}; use pathfinder_common::event::Event; use pathfinder_common::prelude::*; use pathfinder_common::receipt::Receipt; @@ -35,9 +41,14 @@ pub struct Block { /// [`fill`] by setting it to `None`. pub state_update: Option, // Cairo 0 definitions - pub cairo_defs: Vec<(ClassHash, Vec)>, + pub cairo_defs: Vec<(ClassHash, SerializedCairoDefinition)>, // Sierra + Casm definitions + Casm Blake2 hash - pub sierra_defs: Vec<(SierraHash, Vec, Vec, CasmHash)>, + pub sierra_defs: Vec<( + SierraHash, + SerializedSierraDefinition, + SerializedCasmDefinition, + CasmHash, + )>, } pub type BlockHashFn = Box BlockHash>; @@ -335,7 +346,9 @@ pub mod generate { &Faker.fake_with_rng::, _>(rng), ) .unwrap(); - (compute_class_hash(&def).unwrap().hash(), def) + let def = SerializedClassDefinition::from_bytes(def); + let (hash, _) = compute_class_hash(def.clone()).unwrap(); + (hash.hash(), SerializedCairoDefinition::from_bytes(def.into_bytes())) }) .collect::>(); let sierra_defs = (0..num_sierra_classes) @@ -344,11 +357,18 @@ pub mod generate { &Faker.fake_with_rng::, _>(rng), ) .unwrap(); + let def = SerializedClassDefinition::from_bytes(def); + let (hash, _) = compute_class_hash(def.clone()).unwrap(); + let hash = SierraHash(hash.hash().0); + let sierra_def = SerializedSierraDefinition::from_bytes(def.into_bytes()); + let casm_def = SerializedCasmDefinition::from_bytes( + Faker.fake_with_rng::(rng).into_bytes(), + ); ( - SierraHash(compute_class_hash(&def).unwrap().hash().0), + hash, ( - def, - Faker.fake_with_rng::(rng).into_bytes(), + sierra_def, + casm_def, Faker.fake_with_rng::(rng), ), ) diff --git a/crates/storage/src/schema/revision_0076.rs b/crates/storage/src/schema/revision_0076.rs index 0548c38291..06d8e496e6 100644 --- a/crates/storage/src/schema/revision_0076.rs +++ b/crates/storage/src/schema/revision_0076.rs @@ -51,8 +51,12 @@ pub(crate) fn migrate(tx: &rusqlite::Transaction<'_>) -> anyhow::Result<()> { let definition = zstd::decode_all(definition.as_slice()) .map_err(|e| rusqlite::types::FromSqlError::Other(e.into())) .unwrap(); - let computed_hash = - pathfinder_compiler::casm_class_hash_v2(&definition).unwrap(); + let computed_hash = pathfinder_compiler::casm_class_hash_v2( + &pathfinder_common::class_definition::SerializedCasmDefinition::from_bytes( + definition, + ), + ) + .unwrap(); (class_hash, computed_hash) } } diff --git a/crates/validator/src/lib.rs b/crates/validator/src/lib.rs index 6084e14466..9d0d6b350e 100644 --- a/crates/validator/src/lib.rs +++ b/crates/validator/src/lib.rs @@ -12,7 +12,11 @@ use p2p_proto::sync::transaction::{DeclareV3WithoutClass, TransactionVariant as use p2p_proto::transaction::DeclareV3WithClass; use pathfinder_class_hash::compute_sierra_class_hash; use pathfinder_class_hash::json::SierraContractDefinition; -use pathfinder_common::class_definition::{SelectorAndFunctionIndex, SierraEntryPoints}; +use pathfinder_common::class_definition::{ + SelectorAndFunctionIndex, + SerializedSierraDefinition, + SierraEntryPoints, +}; use pathfinder_common::event::Event; use pathfinder_common::receipt::Receipt; use pathfinder_common::state_update::StateUpdateData; @@ -1127,7 +1131,7 @@ fn class_info( .collect(), }, }; - let sierra_def = serde_json::to_vec(&definition)?; + let sierra_def = SerializedSierraDefinition::from_bytes(serde_json::to_vec(&definition)?); let casm_def = pathfinder_compiler::compile_sierra_to_casm( &sierra_def, compiler_resource_limits, From 32d4ab28eb7595e4424b28cacdd26411b71d709c Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Thu, 16 Apr 2026 00:08:21 +0200 Subject: [PATCH 4/8] refactor: rename SerializedClassDefinition into SerializedOpaqueClassDefinition, SerializedClass into SerializedClassDefinition --- crates/class-hash/src/lib.rs | 24 +++++++++---------- crates/common/src/class_definition.rs | 13 +++++----- crates/executor/src/class.rs | 4 ++-- crates/executor/src/state_reader.rs | 4 ++-- .../src/state_reader/storage_adapter.rs | 6 ++--- .../storage_adapter/concurrent.rs | 14 +++++------ crates/feeder-gateway/src/main.rs | 4 ++-- crates/gateway-client/src/lib.rs | 10 ++++---- crates/p2p/src/sync/client/types.rs | 4 ++-- .../pathfinder/examples/compute_class_hash.rs | 2 +- .../src/p2p_network/sync/sync_handlers.rs | 6 ++--- crates/pathfinder/src/state/sync.rs | 6 ++--- crates/pathfinder/src/state/sync/class.rs | 6 ++--- crates/pathfinder/src/state/sync/l2.rs | 20 ++++++++-------- crates/pathfinder/src/state/sync/repair.rs | 8 +++---- crates/pathfinder/src/sync.rs | 6 ++--- crates/pathfinder/src/sync/checkpoint.rs | 10 ++++---- crates/rpc/src/executor.rs | 6 ++--- .../rpc/src/method/add_declare_transaction.rs | 10 ++++---- crates/rpc/src/method/estimate_fee.rs | 8 +++---- .../rpc/src/method/simulate_transactions.rs | 8 +++---- crates/rpc/src/types/class.rs | 24 +++++++++---------- crates/storage/src/connection/class.rs | 24 +++++++++---------- crates/storage/src/fake.rs | 6 ++--- 24 files changed, 116 insertions(+), 117 deletions(-) diff --git a/crates/class-hash/src/lib.rs b/crates/class-hash/src/lib.rs index e331cdf3fc..3f45b239a2 100644 --- a/crates/class-hash/src/lib.rs +++ b/crates/class-hash/src/lib.rs @@ -60,8 +60,8 @@ use anyhow::{Context, Error, Result}; use pathfinder_common::class_definition::EntryPointType::*; use pathfinder_common::class_definition::{ SerializedCairoDefinition, - SerializedClass, SerializedClassDefinition, + SerializedOpaqueClassDefinition, SerializedSierraDefinition, }; use pathfinder_common::{felt_bytes, ClassHash}; @@ -94,8 +94,8 @@ impl ComputedClassHash { /// class definition and then calls the appropriate function to compute the /// class hash with the parsed definition. pub fn compute_class_hash( - serialized_definition: SerializedClassDefinition, -) -> Result<(ComputedClassHash, SerializedClass)> { + serialized_definition: SerializedOpaqueClassDefinition, +) -> Result<(ComputedClassHash, SerializedClassDefinition)> { let contract_definition = parse_contract_definition(&serialized_definition) .context("Failed to parse contract definition")?; @@ -109,7 +109,7 @@ pub fn compute_class_hash( // It is safe to reinterpret the serialized definition as a Sierra definition // since the parsing step succeeded and confirmed it is a // Sierra definition. - SerializedClass::Sierra(SerializedSierraDefinition::from_bytes( + SerializedClassDefinition::Sierra(SerializedSierraDefinition::from_bytes( serialized_definition.into_bytes(), )), ) @@ -122,7 +122,7 @@ pub fn compute_class_hash( hash, // It is safe to reinterpret the serialized definition as a Cairo definition // since the parsing step succeeded and confirmed it is a Cairo definition. - SerializedClass::Cairo(SerializedCairoDefinition::from_bytes( + SerializedClassDefinition::Cairo(SerializedCairoDefinition::from_bytes( serialized_definition.into_bytes(), )), ) @@ -164,7 +164,7 @@ pub fn compute_cairo_hinted_class_hash( /// Due to an issue in serde_json we can't use an untagged enum and simply /// derive a Deserialize implementation: fn parse_contract_definition( - serialized_definition: &SerializedClassDefinition, + serialized_definition: &SerializedOpaqueClassDefinition, ) -> serde_json::Result> { serde_json::from_slice::>(serialized_definition.as_bytes()) .map(json::ContractDefinition::Sierra) @@ -832,14 +832,14 @@ pub mod json { #[cfg(test)] mod test_vectors { - use pathfinder_common::class_definition::SerializedClassDefinition; + use pathfinder_common::class_definition::SerializedOpaqueClassDefinition; use pathfinder_common::macro_prelude::*; use starknet_gateway_test_fixtures::class_definitions::*; use super::super::{compute_class_hash, ComputedClassHash}; fn hash(data: &[u8]) -> ComputedClassHash { - compute_class_hash(SerializedClassDefinition::from_slice(data)) + compute_class_hash(SerializedOpaqueClassDefinition::from_slice(data)) .unwrap() .0 } @@ -885,9 +885,9 @@ pub mod json { // Known contract which triggered a hash mismatch failure. let extract = tokio::task::spawn_blocking(move || -> anyhow::Result<_> { - Ok(compute_class_hash(SerializedClassDefinition::from_slice( - CAIRO_0_8_NEW_ATTRIBUTES, - ))?) + Ok(compute_class_hash( + SerializedOpaqueClassDefinition::from_slice(CAIRO_0_8_NEW_ATTRIBUTES), + )?) }); let (calculated_hash, _) = extract.await.unwrap().unwrap(); @@ -944,7 +944,7 @@ pub mod json { #[tokio::test] async fn cairo_0_11_with_decimal_entry_point_offset() { - let (hash, _) = compute_class_hash(SerializedClassDefinition::from_slice( + let (hash, _) = compute_class_hash(SerializedOpaqueClassDefinition::from_slice( CAIRO_0_11_WITH_DECIMAL_ENTRY_POINT_OFFSET, )) .unwrap(); diff --git a/crates/common/src/class_definition.rs b/crates/common/src/class_definition.rs index 1abff4a59b..c71e2d4e87 100644 --- a/crates/common/src/class_definition.rs +++ b/crates/common/src/class_definition.rs @@ -24,12 +24,12 @@ pub struct SerializedCairoDefinition(Vec); /// Carries the definition of a serialized contract class, either Sierra or /// Cairo. The caller does not care which class definition it is. #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] -pub struct SerializedClassDefinition(Vec); +pub struct SerializedOpaqueClassDefinition(Vec); /// Carries the definition of a serialized contract class, either Sierra or /// Cairo. #[derive(Clone, Debug)] -pub enum SerializedClass { +pub enum SerializedClassDefinition { Sierra(SerializedSierraDefinition), Cairo(SerializedCairoDefinition), } @@ -267,7 +267,7 @@ impl SerializedCairoDefinition { } } -impl SerializedClassDefinition { +impl SerializedOpaqueClassDefinition { pub fn from_bytes(bytes: Vec) -> Self { Self(bytes) } @@ -283,18 +283,17 @@ impl SerializedClassDefinition { pub fn as_bytes(&self) -> &[u8] { &self.0 } - } /// We can use `From` because this is always safe. -impl From for SerializedClassDefinition { +impl From for SerializedOpaqueClassDefinition { fn from(d: SerializedSierraDefinition) -> Self { Self::from_bytes(d.into_bytes()) } } /// We can use `From` because this is always safe. -impl From for SerializedClassDefinition { +impl From for SerializedOpaqueClassDefinition { fn from(d: SerializedCairoDefinition) -> Self { Self::from_bytes(d.into_bytes()) } @@ -322,7 +321,7 @@ impl Dummy for SerializedCairoDefinition { } // TODO derive? -impl Dummy for SerializedClassDefinition { +impl Dummy for SerializedOpaqueClassDefinition { fn dummy_with_rng(_: &T, rng: &mut R) -> Self { Self(Faker.fake_with_rng(rng)) } diff --git a/crates/executor/src/class.rs b/crates/executor/src/class.rs index 2a246bbafa..55c52b906e 100644 --- a/crates/executor/src/class.rs +++ b/crates/executor/src/class.rs @@ -1,8 +1,8 @@ use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; -use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedClassDefinition}; +use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedOpaqueClassDefinition}; pub fn parse_deprecated_class_definition( - definition: SerializedClassDefinition, + definition: SerializedOpaqueClassDefinition, ) -> anyhow::Result { let class: starknet_api::deprecated_contract_class::ContractClass = serde_json::from_slice(definition.as_bytes())?; diff --git a/crates/executor/src/state_reader.rs b/crates/executor/src/state_reader.rs index abfa6ab28c..6b06736096 100644 --- a/crates/executor/src/state_reader.rs +++ b/crates/executor/src/state_reader.rs @@ -4,7 +4,7 @@ use blockifier::execution::contract_class::RunnableCompiledClass; use blockifier::state::errors::StateError; use blockifier::state::state_api::StateReader; use cached::Cached; -use pathfinder_common::class_definition::SerializedClassDefinition; +use pathfinder_common::class_definition::SerializedOpaqueClassDefinition; use pathfinder_common::{BlockNumber, ClassHash, StorageAddress, StorageValue}; use pathfinder_crypto::Felt; use starknet_api::contract_class::compiled_class_hash::{HashVersion, HashableCompiledClass}; @@ -181,7 +181,7 @@ impl PathfinderStateReader { fn try_sierra_version_from_class( &self, - class_definition: &SerializedClassDefinition, + class_definition: &SerializedOpaqueClassDefinition, ) -> Result { use cairo_vm::types::errors::program_errors::ProgramError; diff --git a/crates/executor/src/state_reader/storage_adapter.rs b/crates/executor/src/state_reader/storage_adapter.rs index 105d5d38a0..0f140f7186 100644 --- a/crates/executor/src/state_reader/storage_adapter.rs +++ b/crates/executor/src/state_reader/storage_adapter.rs @@ -1,6 +1,6 @@ use blockifier::blockifier::config::TransactionExecutorConfig; use blockifier::state::errors::StateError; -use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedClassDefinition}; +use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedOpaqueClassDefinition}; use pathfinder_common::{ BlockHash, BlockId, @@ -17,8 +17,8 @@ pub mod concurrent; pub mod rc; // Keep clippy happy -type ClassDefinitionAtWithBlockNumber = Option<(BlockNumber, SerializedClassDefinition)>; -type ClassDefinitionWithBlockNumber = Option<(Option, SerializedClassDefinition)>; +type ClassDefinitionAtWithBlockNumber = Option<(BlockNumber, SerializedOpaqueClassDefinition)>; +type ClassDefinitionWithBlockNumber = Option<(Option, SerializedOpaqueClassDefinition)>; pub trait StorageAdapter { fn transaction_executor_config(&self) -> TransactionExecutorConfig; diff --git a/crates/executor/src/state_reader/storage_adapter/concurrent.rs b/crates/executor/src/state_reader/storage_adapter/concurrent.rs index 1b5363a5b0..d9321d442f 100644 --- a/crates/executor/src/state_reader/storage_adapter/concurrent.rs +++ b/crates/executor/src/state_reader/storage_adapter/concurrent.rs @@ -413,7 +413,7 @@ mod decided { use pathfinder_common::class_definition::{ SerializedCasmDefinition, - SerializedClassDefinition, + SerializedOpaqueClassDefinition, }; use pathfinder_common::state_update::ContractUpdate; use pathfinder_common::{ @@ -478,7 +478,7 @@ mod decided { pub fn class_definition_with_block_number( decided_blocks: &DecidedBlocks, class_hash: ClassHash, - ) -> Option<(Option, SerializedClassDefinition)> { + ) -> Option<(Option, SerializedOpaqueClassDefinition)> { let decided_blocks = decided_blocks.read().unwrap(); find_class(decided_blocks.values(), class_hash) .map(|(b, c)| (Some(b), c.sierra_def.clone().into())) @@ -704,7 +704,7 @@ mod decided { class_definition_with_block_number(&two(), ClassHash::ZERO), Some(( Some(BlockNumber::GENESIS), - SerializedClassDefinition::from_slice(&[0]) + SerializedOpaqueClassDefinition::from_slice(&[0]) )) ); } @@ -811,7 +811,7 @@ mod decided { ), Some(( BlockNumber::GENESIS, - SerializedClassDefinition::from_slice(&[0]) + SerializedOpaqueClassDefinition::from_slice(&[0]) )) ); } @@ -828,7 +828,7 @@ mod decided { ), Some(( BlockNumber::GENESIS, - SerializedClassDefinition::from_slice(&[0]) + SerializedOpaqueClassDefinition::from_slice(&[0]) )) ); } @@ -859,7 +859,7 @@ mod decided { class_definition_at_with_block_number(&one(), BlockId::Latest, ClassHash::ZERO), Some(( BlockNumber::GENESIS, - SerializedClassDefinition::from_slice(&[0]) + SerializedOpaqueClassDefinition::from_slice(&[0]) )) ); } @@ -870,7 +870,7 @@ mod decided { class_definition_at_with_block_number(&two(), BlockId::Latest, ClassHash::ZERO), Some(( BlockNumber::GENESIS, - SerializedClassDefinition::from_slice(&[0]) + SerializedOpaqueClassDefinition::from_slice(&[0]) )) ); } diff --git a/crates/feeder-gateway/src/main.rs b/crates/feeder-gateway/src/main.rs index 2e4a60ebc4..52b905588f 100644 --- a/crates/feeder-gateway/src/main.rs +++ b/crates/feeder-gateway/src/main.rs @@ -37,7 +37,7 @@ use pathfinder_block_commitments::{ calculate_receipt_commitment, calculate_transaction_commitment, }; -use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedClassDefinition}; +use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedOpaqueClassDefinition}; use pathfinder_common::integration_testing::debug_create_port_marker_file; use pathfinder_common::prelude::*; use pathfinder_common::state_update::ContractClassUpdate; @@ -824,7 +824,7 @@ fn resolve_state_update( fn resolve_class( tx: &pathfinder_storage::Transaction<'_>, class_hash: ClassHash, -) -> anyhow::Result { +) -> anyhow::Result { let definition = tx .class_definition(class_hash) .context("Reading class definition from database")? diff --git a/crates/gateway-client/src/lib.rs b/crates/gateway-client/src/lib.rs index 6b04dbcae0..0e9ae26cc1 100644 --- a/crates/gateway-client/src/lib.rs +++ b/crates/gateway-client/src/lib.rs @@ -5,7 +5,7 @@ use std::sync::{Arc, RwLock}; use std::time::Duration; use anyhow::Context; -use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedClassDefinition}; +use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedOpaqueClassDefinition}; use pathfinder_common::prelude::*; use reqwest::Url; use starknet_gateway_types::error::SequencerError; @@ -73,7 +73,7 @@ pub trait GatewayApi: Sync { &self, class_hash: ClassHash, block: BlockId, - ) -> Result { + ) -> Result { unimplemented!(); } @@ -176,7 +176,7 @@ impl GatewayApi for Arc { &self, class_hash: ClassHash, block: BlockId, - ) -> Result { + ) -> Result { self.as_ref().class_by_hash(class_hash, block).await } @@ -557,7 +557,7 @@ impl GatewayApi for Client { &self, class_hash: ClassHash, block: BlockId, - ) -> Result { + ) -> Result { let bytes = self .feeder_gateway_request() .get_class_by_hash() @@ -566,7 +566,7 @@ impl GatewayApi for Client { .retry(self.retry) .get_as_bytes() .await?; - Ok(SerializedClassDefinition::from_bytes(bytes.to_vec())) + Ok(SerializedOpaqueClassDefinition::from_bytes(bytes.to_vec())) } /// Gets CASM for a particular class hash. diff --git a/crates/p2p/src/sync/client/types.rs b/crates/p2p/src/sync/client/types.rs index c641ff0d92..2a4b15c022 100644 --- a/crates/p2p/src/sync/client/types.rs +++ b/crates/p2p/src/sync/client/types.rs @@ -3,7 +3,7 @@ use fake::Dummy; use libp2p::PeerId; use pathfinder_common::class_definition::{ SerializedCairoDefinition, - SerializedClassDefinition, + SerializedOpaqueClassDefinition, SerializedSierraDefinition, }; use pathfinder_common::event::Event; @@ -31,7 +31,7 @@ pub enum ClassDefinition { impl ClassDefinition { /// Return Cairo or Sierra class definition depending on the variant. - pub fn class_definition(&self) -> SerializedClassDefinition { + pub fn class_definition(&self) -> SerializedOpaqueClassDefinition { match self { Self::Cairo { definition, .. } => definition.clone().into(), Self::Sierra { diff --git a/crates/pathfinder/examples/compute_class_hash.rs b/crates/pathfinder/examples/compute_class_hash.rs index a4e4e322ac..6d3cb5eda5 100644 --- a/crates/pathfinder/examples/compute_class_hash.rs +++ b/crates/pathfinder/examples/compute_class_hash.rs @@ -11,7 +11,7 @@ fn main() -> Result<(), Box> { let mut s = Vec::new(); std::io::stdin().read_to_end(&mut s).unwrap(); let definition = - pathfinder_common::class_definition::SerializedClassDefinition::from_bytes(s); + pathfinder_common::class_definition::SerializedOpaqueClassDefinition::from_bytes(s); let (hash, _) = pathfinder_class_hash::compute_class_hash(definition)?; let class_hash = hash.hash(); println!("{:x}", class_hash.0); diff --git a/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs b/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs index fb79c280f0..48eca3a189 100644 --- a/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs +++ b/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs @@ -22,7 +22,7 @@ use p2p_proto::sync::transaction::{ use pathfinder_common::class_definition::{ self, SerializedCasmDefinition, - SerializedClassDefinition, + SerializedOpaqueClassDefinition, }; use pathfinder_common::{BlockHash, BlockNumber, SignedBlockHeader}; use pathfinder_storage::{Storage, Transaction}; @@ -151,9 +151,9 @@ fn get_header( #[derive(Debug, Clone)] enum ClassDefinition { - Cairo(SerializedClassDefinition), + Cairo(SerializedOpaqueClassDefinition), Sierra { - sierra: SerializedClassDefinition, + sierra: SerializedOpaqueClassDefinition, _casm: SerializedCasmDefinition, }, } diff --git a/crates/pathfinder/src/state/sync.rs b/crates/pathfinder/src/state/sync.rs index 0413176da3..ed53f6ed90 100644 --- a/crates/pathfinder/src/state/sync.rs +++ b/crates/pathfinder/src/state/sync.rs @@ -1637,7 +1637,7 @@ mod tests { use pathfinder_common::class_definition::{ SerializedCairoDefinition, SerializedCasmDefinition, - SerializedClassDefinition, + SerializedOpaqueClassDefinition, SerializedSierraDefinition, }; use pathfinder_common::event::Event; @@ -2344,7 +2344,7 @@ mod tests { assert_eq!( definition, - SerializedClassDefinition::from(expected_definition) + SerializedOpaqueClassDefinition::from(expected_definition) ); } @@ -2395,7 +2395,7 @@ mod tests { assert_eq!( definition, - SerializedClassDefinition::from(expected_definition) + SerializedOpaqueClassDefinition::from(expected_definition) ); let casm_hash_v2 = tx.casm_hash_v2(ClassHash(class_hash)).unwrap().unwrap(); diff --git a/crates/pathfinder/src/state/sync/class.rs b/crates/pathfinder/src/state/sync/class.rs index 7c4aa05711..f26b35a18e 100644 --- a/crates/pathfinder/src/state/sync/class.rs +++ b/crates/pathfinder/src/state/sync/class.rs @@ -2,7 +2,7 @@ use anyhow::Context; use pathfinder_common::class_definition::{ SerializedCairoDefinition, SerializedCasmDefinition, - SerializedClass, + SerializedClassDefinition, SerializedSierraDefinition, }; use pathfinder_common::{CasmHash, ClassHash, SierraHash}; @@ -44,14 +44,14 @@ pub async fn download_class( use pathfinder_class_hash::ComputedClassHash; match (hash, serialized_class) { - (ComputedClassHash::Cairo(hash), SerializedClass::Cairo(definition)) => { + (ComputedClassHash::Cairo(hash), SerializedClassDefinition::Cairo(definition)) => { if class_hash != hash { tracing::warn!(expected=%class_hash, computed=%hash, "Cairo 0 class hash mismatch"); } Ok(DownloadedClass::Cairo { definition, hash }) } - (ComputedClassHash::Sierra(hash), SerializedClass::Sierra(sierra_definition)) => { + (ComputedClassHash::Sierra(hash), SerializedClassDefinition::Sierra(sierra_definition)) => { anyhow::ensure!( class_hash == hash, "Class hash mismatch, {} instead of {}", diff --git a/crates/pathfinder/src/state/sync/l2.rs b/crates/pathfinder/src/state/sync/l2.rs index 1673d585d2..9c7471af0f 100644 --- a/crates/pathfinder/src/state/sync/l2.rs +++ b/crates/pathfinder/src/state/sync/l2.rs @@ -1603,7 +1603,7 @@ mod tests { use std::sync::LazyLock; use assert_matches::assert_matches; - use pathfinder_common::class_definition::SerializedClassDefinition; + use pathfinder_common::class_definition::SerializedOpaqueClassDefinition; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_common::Chain; @@ -1855,17 +1855,17 @@ mod tests { }) } - static CONTRACT0_DEF: LazyLock = + static CONTRACT0_DEF: LazyLock = LazyLock::new(|| { - SerializedClassDefinition::from_bytes(format!("{DEF0}0{DEF1}").into_bytes()) + SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}0{DEF1}").into_bytes()) }); - static CONTRACT0_DEF_V2: LazyLock = + static CONTRACT0_DEF_V2: LazyLock = LazyLock::new(|| { - SerializedClassDefinition::from_bytes(format!("{DEF0}0 v2{DEF1}").into_bytes()) + SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}0 v2{DEF1}").into_bytes()) }); - static CONTRACT1_DEF: LazyLock = + static CONTRACT1_DEF: LazyLock = LazyLock::new(|| { - SerializedClassDefinition::from_bytes(format!("{DEF0}1{DEF1}").into_bytes()) + SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}1{DEF1}").into_bytes()) }); static BLOCK0: LazyLock = LazyLock::new(|| reply::Block { @@ -2142,7 +2142,7 @@ mod tests { mock: &mut MockGatewayApi, seq: &mut mockall::Sequence, class_hash: ClassHash, - returned_result: Result, + returned_result: Result, ) { mock.expect_class_by_hash() .withf(move |x, _| x == &class_hash) @@ -2155,7 +2155,7 @@ mod tests { fn expect_class_by_hash_no_sequence( mock: &mut MockGatewayApi, class_hash: ClassHash, - returned_result: Result, + returned_result: Result, ) { mock.expect_class_by_hash() .withf(move |x, _| x == &class_hash) @@ -2166,7 +2166,7 @@ mod tests { fn expect_class_by_hash_no_sequence_at_most_once( mock: &mut MockGatewayApi, class_hash: ClassHash, - returned_result: Result, + returned_result: Result, ) { mock.expect_class_by_hash() .withf(move |x, _| x == &class_hash) diff --git a/crates/pathfinder/src/state/sync/repair.rs b/crates/pathfinder/src/state/sync/repair.rs index 53350b67d6..8cb193aee1 100644 --- a/crates/pathfinder/src/state/sync/repair.rs +++ b/crates/pathfinder/src/state/sync/repair.rs @@ -155,7 +155,7 @@ mod tests { use pathfinder_common::class_definition::{ SerializedCairoDefinition, - SerializedClassDefinition, + SerializedOpaqueClassDefinition, }; use pathfinder_common::state_update::StateUpdateData; use pathfinder_common::BlockNumber; @@ -218,7 +218,7 @@ mod tests { let mut db = storage.connection().unwrap(); let tx = db.transaction().unwrap(); let stored = tx.class_definition(hash).unwrap(); - assert_eq!(stored, Some(SerializedClassDefinition::from(definition))); + assert_eq!(stored, Some(SerializedOpaqueClassDefinition::from(definition))); } /// Cairo 0 classes can have a mismatch between the declared hash and the @@ -254,7 +254,7 @@ mod tests { // Stored under the declared hash, not the computed one. assert_eq!( tx.class_definition(declared).unwrap(), - Some(SerializedClassDefinition::from(definition)) + Some(SerializedOpaqueClassDefinition::from(definition)) ); assert_eq!(tx.class_definition(computed).unwrap(), None); } @@ -301,7 +301,7 @@ mod tests { let tx = db.transaction().unwrap(); assert_eq!( tx.class_definition(good).unwrap(), - Some(SerializedClassDefinition::from(definition)) + Some(SerializedOpaqueClassDefinition::from(definition)) ); // bad was not repaired — definition IS NULL, so it still appears in // the missing list. diff --git a/crates/pathfinder/src/sync.rs b/crates/pathfinder/src/sync.rs index 5360557bca..9cd497043c 100644 --- a/crates/pathfinder/src/sync.rs +++ b/crates/pathfinder/src/sync.rs @@ -321,7 +321,7 @@ mod tests { use pathfinder_common::class_definition::{ SerializedCairoDefinition, SerializedCasmDefinition, - SerializedClassDefinition, + SerializedOpaqueClassDefinition, SerializedSierraDefinition, }; use pathfinder_common::event::Event; @@ -622,7 +622,7 @@ mod tests { expected .cairo_defs .into_iter() - .map(|(h, d)| (h, SerializedClassDefinition::from(d))) + .map(|(h, d)| (h, SerializedOpaqueClassDefinition::from(d))) .collect::>(), "block {}", block_number @@ -636,7 +636,7 @@ mod tests { .map(|(h, s, _, _)| ( h, ( - SerializedClassDefinition::from(s), + SerializedOpaqueClassDefinition::from(s), SerializedCasmDefinition::from_slice( starknet_gateway_test_fixtures::class_definitions::CAIRO_1_1_0_BALANCE_CASM_JSON ), diff --git a/crates/pathfinder/src/sync/checkpoint.rs b/crates/pathfinder/src/sync/checkpoint.rs index b3e9a55ca3..b8d44750f3 100644 --- a/crates/pathfinder/src/sync/checkpoint.rs +++ b/crates/pathfinder/src/sync/checkpoint.rs @@ -1373,7 +1373,7 @@ mod tests { use pathfinder_common::class_definition::{ SerializedCairoDefinition, SerializedCasmDefinition, - SerializedClassDefinition, + SerializedOpaqueClassDefinition, SerializedSierraDefinition, }; use pathfinder_common::event::Event; @@ -1447,7 +1447,7 @@ mod tests { struct Setup { pub streamed_classes: Vec, anyhow::Error>>, pub declared_classes: DeclaredClasses, - pub expected_defs: HashMap, + pub expected_defs: HashMap, pub storage: Storage, } @@ -1536,14 +1536,14 @@ mod tests { ]); let expected_defs = [ - (cairo_hash, SerializedClassDefinition::from_slice(CAIRO)), + (cairo_hash, SerializedOpaqueClassDefinition::from_slice(CAIRO)), ( ClassHash(sierra0_hash.0), - SerializedClassDefinition::from_slice(SIERRA0), + SerializedOpaqueClassDefinition::from_slice(SIERRA0), ), ( ClassHash(sierra2_hash.0), - SerializedClassDefinition::from_slice(SIERRA2), + SerializedOpaqueClassDefinition::from_slice(SIERRA2), ), ] .into(); diff --git a/crates/rpc/src/executor.rs b/crates/rpc/src/executor.rs index a30fb129df..b097af7925 100644 --- a/crates/rpc/src/executor.rs +++ b/crates/rpc/src/executor.rs @@ -1,5 +1,5 @@ use anyhow::Context; -use pathfinder_common::class_definition::{SerializedClassDefinition, SerializedSierraDefinition}; +use pathfinder_common::class_definition::{SerializedOpaqueClassDefinition, SerializedSierraDefinition}; use pathfinder_common::transaction::TransactionVariant; use pathfinder_common::{BlockNumber, ChainId, StarknetVersion}; use pathfinder_executor::types::to_starknet_api_transaction; @@ -93,7 +93,7 @@ pub(crate) fn map_broadcasted_transaction( .context("Serializing Cairo class to JSON")?; let contract_class = pathfinder_executor::parse_deprecated_class_definition( - SerializedClassDefinition::from_bytes(contract_class_json), + SerializedOpaqueClassDefinition::from_bytes(contract_class_json), )?; Some(ClassInfo::new( @@ -110,7 +110,7 @@ pub(crate) fn map_broadcasted_transaction( .context("Serializing Cairo class to JSON")?; let contract_class = pathfinder_executor::parse_deprecated_class_definition( - SerializedClassDefinition::from_bytes(contract_class_json), + SerializedOpaqueClassDefinition::from_bytes(contract_class_json), )?; Some(ClassInfo::new( diff --git a/crates/rpc/src/method/add_declare_transaction.rs b/crates/rpc/src/method/add_declare_transaction.rs index 5d58b0b737..bf8591cea1 100644 --- a/crates/rpc/src/method/add_declare_transaction.rs +++ b/crates/rpc/src/method/add_declare_transaction.rs @@ -464,7 +464,7 @@ impl crate::dto::SerializeForVersion for Output { mod tests { use std::sync::LazyLock; - use pathfinder_common::class_definition::SerializedClassDefinition; + use pathfinder_common::class_definition::SerializedOpaqueClassDefinition; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_common::transaction::{DataAvailabilityMode, ResourceBound, ResourceBounds}; @@ -486,7 +486,7 @@ mod tests { use crate::types::ContractClass; pub static CONTRACT_CLASS: LazyLock = LazyLock::new(|| { - ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(CONTRACT_DEFINITION)) + ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(CONTRACT_DEFINITION)) .unwrap() .as_cairo() .unwrap() @@ -503,21 +503,21 @@ mod tests { .get_mut("prime") .unwrap() = serde_json::json!("0x1"); let definition = serde_json::to_vec(&definition).unwrap(); - ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(&definition)) + ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(&definition)) .unwrap() .as_cairo() .unwrap() }); pub static SIERRA_CLASS: LazyLock = LazyLock::new(|| { - ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(CAIRO_2_0_0_STACK_OVERFLOW)) + ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(CAIRO_2_0_0_STACK_OVERFLOW)) .unwrap() .as_sierra() .unwrap() }); pub static INTEGRATION_SIERRA_CLASS: LazyLock = LazyLock::new(|| { - ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(include_bytes!( + ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(include_bytes!( "../../fixtures/contracts/\ integration_class_0x5ae9d09292a50ed48c5930904c880dab56e85b825022a7d689cfc9e65e01ee7.\ json" diff --git a/crates/rpc/src/method/estimate_fee.rs b/crates/rpc/src/method/estimate_fee.rs index 1a4039641f..1c0ac05c95 100644 --- a/crates/rpc/src/method/estimate_fee.rs +++ b/crates/rpc/src/method/estimate_fee.rs @@ -232,7 +232,7 @@ impl crate::dto::SerializeForVersion for Output { #[cfg(test)] mod tests { use assert_matches::assert_matches; - use pathfinder_common::class_definition::SerializedClassDefinition; + use pathfinder_common::class_definition::SerializedOpaqueClassDefinition; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_common::transaction::{DataAvailabilityMode, ResourceBound, ResourceBounds}; @@ -267,7 +267,7 @@ mod tests { casm_hash!("0x069032ff71f77284e1a0864a573007108ca5cc08089416af50f03260f5d6d4d8"); let contract_class: SierraContractClass = - ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(sierra_definition)) + ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(sierra_definition)) .unwrap() .as_sierra() .unwrap(); @@ -606,7 +606,7 @@ mod tests { casm_hash!("0x02F58B23F7D98FF076AE59C08125AAFFD6DECCF1A7E97378D1A303B1A4223989"); let contract_class: SierraContractClass = - ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(sierra_definition)) + ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(sierra_definition)) .unwrap() .as_sierra() .unwrap(); @@ -642,7 +642,7 @@ mod tests { casm_hash!("0x138cd11c6de707426665bd8b0425d7411bb8dc5cbee15867025007a933b3379"); let contract_class: SierraContractClass = - ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(sierra_definition)) + ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(sierra_definition)) .unwrap() .as_sierra() .unwrap(); diff --git a/crates/rpc/src/method/simulate_transactions.rs b/crates/rpc/src/method/simulate_transactions.rs index b94f564d3a..9d20871d3e 100644 --- a/crates/rpc/src/method/simulate_transactions.rs +++ b/crates/rpc/src/method/simulate_transactions.rs @@ -297,7 +297,7 @@ pub(crate) mod tests { use std::collections::{BTreeMap, HashSet}; use assert_matches::assert_matches; - use pathfinder_common::class_definition::SerializedClassDefinition; + use pathfinder_common::class_definition::SerializedOpaqueClassDefinition; use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; use pathfinder_common::transaction::{DataAvailabilityMode, ResourceBound, ResourceBounds}; @@ -718,7 +718,7 @@ pub(crate) mod tests { pub const CAIRO0_HASH: ClassHash = class_hash!("02c52e7084728572ea940b4df708a2684677c19fa6296de2ea7ba5327e3a84ef"); - let contract_class = crate::types::ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(CAIRO0_DEFINITION)) + let contract_class = crate::types::ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(CAIRO0_DEFINITION)) .unwrap() .as_cairo() .unwrap(); @@ -930,7 +930,7 @@ pub(crate) mod tests { pub fn declare(account_contract_address: ContractAddress) -> BroadcastedTransaction { let contract_class = - crate::types::ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(SIERRA_DEFINITION)) + crate::types::ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(SIERRA_DEFINITION)) .unwrap() .as_sierra() .unwrap(); @@ -956,7 +956,7 @@ pub(crate) mod tests { let contract_definition = include_bytes!("../../fixtures/contracts/libfuncs_coverage.json"); let contract_class = - crate::types::ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(contract_definition)) + crate::types::ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(contract_definition)) .unwrap() .as_sierra() .unwrap(); diff --git a/crates/rpc/src/types/class.rs b/crates/rpc/src/types/class.rs index dc5833cd18..4f6175a7e7 100644 --- a/crates/rpc/src/types/class.rs +++ b/crates/rpc/src/types/class.rs @@ -1,6 +1,6 @@ use anyhow::Context; use base64::prelude::*; -use pathfinder_common::class_definition::SerializedClassDefinition; +use pathfinder_common::class_definition::SerializedOpaqueClassDefinition; #[derive(Clone, Debug, PartialEq, Eq)] pub enum ContractClass { @@ -21,7 +21,7 @@ impl ContractClass { /// Note that this function does not validate the class definition in any /// way, so this is only ever to be called for trusted data from storage. pub fn try_from_serialized_definition( - serialized_definition: &SerializedClassDefinition, + serialized_definition: &SerializedOpaqueClassDefinition, ) -> anyhow::Result { let mut json = serde_json::from_slice::(serialized_definition.as_bytes()) .context("Parsing json")?; @@ -232,7 +232,7 @@ pub mod cairo { impl CairoContractClass { pub fn class_hash(&self) -> anyhow::Result { let serialized = self.serialize_to_json()?; - let definition = pathfinder_common::class_definition::SerializedClassDefinition::from_bytes(serialized); + let definition = pathfinder_common::class_definition::SerializedOpaqueClassDefinition::from_bytes(serialized); compute_class_hash(definition) .map(|(hash, _)| hash) @@ -694,7 +694,7 @@ pub mod sierra { impl SierraContractClass { pub fn class_hash(&self) -> anyhow::Result { let definition = serde_json::to_vec(self)?; - let definition = pathfinder_common::class_definition::SerializedClassDefinition::from_bytes(definition); + let definition = pathfinder_common::class_definition::SerializedOpaqueClassDefinition::from_bytes(definition); compute_class_hash(definition).map(|(hash, _)| hash) } } @@ -787,7 +787,7 @@ mod tests { mod declare_class_hash { use pathfinder_class_hash::compute_class_hash; - use pathfinder_common::class_definition::SerializedClassDefinition; + use pathfinder_common::class_definition::SerializedOpaqueClassDefinition; use starknet_gateway_test_fixtures::class_definitions::{ CAIRO_0_11_SIERRA, CONTRACT_DEFINITION, @@ -798,11 +798,11 @@ mod tests { #[test] fn compute_sierra_class_hash() { let (class_hash, _) = - compute_class_hash(SerializedClassDefinition::from_slice(CAIRO_0_11_SIERRA)) + compute_class_hash(SerializedOpaqueClassDefinition::from_slice(CAIRO_0_11_SIERRA)) .unwrap(); let class = ContractClass::try_from_serialized_definition( - &SerializedClassDefinition::from_slice(CAIRO_0_11_SIERRA), + &SerializedOpaqueClassDefinition::from_slice(CAIRO_0_11_SIERRA), ) .unwrap(); assert_eq!(class.class_hash().unwrap(), class_hash); @@ -811,11 +811,11 @@ mod tests { #[test] fn compute_cairo_class_hash() { let (class_hash, _) = - compute_class_hash(SerializedClassDefinition::from_slice(CONTRACT_DEFINITION)) + compute_class_hash(SerializedOpaqueClassDefinition::from_slice(CONTRACT_DEFINITION)) .unwrap(); let class = ContractClass::try_from_serialized_definition( - &SerializedClassDefinition::from_slice(CONTRACT_DEFINITION), + &SerializedOpaqueClassDefinition::from_slice(CONTRACT_DEFINITION), ) .unwrap(); assert_eq!(class.class_hash().unwrap(), class_hash); @@ -823,7 +823,7 @@ mod tests { } mod contract_class_serialization { - use pathfinder_common::class_definition::SerializedClassDefinition; + use pathfinder_common::class_definition::SerializedOpaqueClassDefinition; use pathfinder_executor::parse_deprecated_class_definition; use super::super::cairo::CairoContractClass; @@ -850,7 +850,7 @@ mod tests { let serialized_definition = contract_class.serialize_to_json().unwrap(); - parse_deprecated_class_definition(SerializedClassDefinition::from_bytes( + parse_deprecated_class_definition(SerializedOpaqueClassDefinition::from_bytes( serialized_definition, )) .unwrap(); @@ -860,7 +860,7 @@ mod tests { fn parse_deprecated_class_definition_with_debug_info() { let definition = include_bytes!("../../fixtures/contracts/cairo0_open_zeppelin_class.json"); - let class = ContractClass::try_from_serialized_definition(&SerializedClassDefinition::from_slice(definition)).unwrap(); + let class = ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(definition)).unwrap(); // this step involves parsing the full program including debug info class.as_cairo().unwrap().serialize_to_json().unwrap(); diff --git a/crates/storage/src/connection/class.rs b/crates/storage/src/connection/class.rs index cacda2df4f..1f373a078e 100644 --- a/crates/storage/src/connection/class.rs +++ b/crates/storage/src/connection/class.rs @@ -2,7 +2,7 @@ use anyhow::Context; use pathfinder_common::class_definition::{ SerializedCairoDefinition, SerializedCasmDefinition, - SerializedClassDefinition, + SerializedOpaqueClassDefinition, SerializedSierraDefinition, }; use pathfinder_common::{ @@ -183,7 +183,7 @@ impl Transaction<'_> { pub fn class_definition( &self, class_hash: ClassHash, - ) -> anyhow::Result> { + ) -> anyhow::Result> { self.class_definition_with_block_number(class_hash) .map(|option| option.map(|(_block_number, definition)| definition)) } @@ -193,7 +193,7 @@ impl Transaction<'_> { pub fn class_definition_with_block_number( &self, class_hash: ClassHash, - ) -> anyhow::Result, SerializedClassDefinition)>> { + ) -> anyhow::Result, SerializedOpaqueClassDefinition)>> { let from_row = |row: &rusqlite::Row<'_>| { let definition = row.get_blob(0).map(|x| x.to_vec())?; let block_number = row.get_optional_block_number(1)?; @@ -217,7 +217,7 @@ impl Transaction<'_> { Ok(Some(( block_number, - SerializedClassDefinition::from_bytes(definition), + SerializedOpaqueClassDefinition::from_bytes(definition), ))) } @@ -272,7 +272,7 @@ impl Transaction<'_> { &self, block_id: BlockId, class_hash: ClassHash, - ) -> anyhow::Result> { + ) -> anyhow::Result> { self.class_definition_at_with_block_number(block_id, class_hash) .map(|option| option.map(|(_, definition)| definition)) } @@ -283,7 +283,7 @@ impl Transaction<'_> { &self, block_id: BlockId, class_hash: ClassHash, - ) -> anyhow::Result> { + ) -> anyhow::Result> { let definition = self.compressed_class_definition_at_with_block_number(block_id, class_hash)?; let Some((block_number, definition)) = definition else { @@ -291,7 +291,7 @@ impl Transaction<'_> { }; let definition = zstd::decode_all(definition.as_slice()).context("Decompressing class definition")?; - let definition = SerializedClassDefinition::from_bytes(definition); + let definition = SerializedOpaqueClassDefinition::from_bytes(definition); Ok(Some((block_number, definition))) } @@ -645,7 +645,7 @@ mod tests { let result = tx.class_definition(hash).unwrap(); assert_eq!( result, - Some(SerializedClassDefinition::from_slice(definition)) + Some(SerializedOpaqueClassDefinition::from_slice(definition)) ); } @@ -676,7 +676,7 @@ mod tests { let result = tx.class_definition(class_hash).unwrap(); assert_eq!( result, - Some(SerializedClassDefinition::from_slice(sierra_definition)) + Some(SerializedOpaqueClassDefinition::from_slice(sierra_definition)) ); let result = tx.casm_definition(class_hash).unwrap(); @@ -712,7 +712,7 @@ mod tests { let result = tx.class_definition(hash).unwrap(); assert_eq!( result, - Some(SerializedClassDefinition::from_slice(definition_a)) + Some(SerializedOpaqueClassDefinition::from_slice(definition_a)) ); } @@ -771,7 +771,7 @@ mod tests { assert_eq!( definition, - SerializedClassDefinition::from_slice(cairo_definition) + SerializedOpaqueClassDefinition::from_slice(cairo_definition) ); } @@ -811,7 +811,7 @@ mod tests { .unwrap(); assert_eq!( definition, - SerializedClassDefinition::from_slice(sierra_definition) + SerializedOpaqueClassDefinition::from_slice(sierra_definition) ); let retrieved_casm_hash_v2 = tx.casm_hash_v2(ClassHash(sierra_hash.0)).unwrap().unwrap(); diff --git a/crates/storage/src/fake.rs b/crates/storage/src/fake.rs index 27bdd15fd5..7bd50cdb07 100644 --- a/crates/storage/src/fake.rs +++ b/crates/storage/src/fake.rs @@ -7,7 +7,7 @@ use pathfinder_class_hash::compute_class_hash; use pathfinder_common::class_definition::{ SerializedCairoDefinition, SerializedCasmDefinition, - SerializedClassDefinition, + SerializedOpaqueClassDefinition, SerializedSierraDefinition, }; use pathfinder_common::event::Event; @@ -346,7 +346,7 @@ pub mod generate { &Faker.fake_with_rng::, _>(rng), ) .unwrap(); - let def = SerializedClassDefinition::from_bytes(def); + let def = SerializedOpaqueClassDefinition::from_bytes(def); let (hash, _) = compute_class_hash(def.clone()).unwrap(); (hash.hash(), SerializedCairoDefinition::from_bytes(def.into_bytes())) }) @@ -357,7 +357,7 @@ pub mod generate { &Faker.fake_with_rng::, _>(rng), ) .unwrap(); - let def = SerializedClassDefinition::from_bytes(def); + let def = SerializedOpaqueClassDefinition::from_bytes(def); let (hash, _) = compute_class_hash(def.clone()).unwrap(); let hash = SierraHash(hash.hash().0); let sierra_def = SerializedSierraDefinition::from_bytes(def.into_bytes()); From 01ce04a19b9f6ff0a47790c0a6d8f5ae5df9d4b2 Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Thu, 16 Apr 2026 00:09:13 +0200 Subject: [PATCH 5/8] chore: fmt --- crates/executor/src/class.rs | 5 ++- .../src/state_reader/storage_adapter.rs | 8 +++-- crates/feeder-gateway/src/main.rs | 5 ++- crates/gateway-client/src/lib.rs | 5 ++- .../examples/recompute_casm_class_hashes.rs | 4 ++- crates/pathfinder/src/state/sync/l2.rs | 21 +++++------ crates/pathfinder/src/state/sync/repair.rs | 5 ++- crates/pathfinder/src/sync/checkpoint.rs | 5 ++- crates/rpc/src/executor.rs | 19 ++++++---- .../rpc/src/method/add_declare_transaction.rs | 36 +++++++++++-------- crates/rpc/src/method/estimate_fee.rs | 33 +++++++++-------- .../rpc/src/method/simulate_transactions.rs | 32 +++++++++-------- crates/rpc/src/types/class.rs | 34 ++++++++++++------ crates/storage/src/connection/class.rs | 4 ++- crates/storage/src/fake.rs | 5 ++- 15 files changed, 138 insertions(+), 83 deletions(-) diff --git a/crates/executor/src/class.rs b/crates/executor/src/class.rs index 55c52b906e..eed4e254c8 100644 --- a/crates/executor/src/class.rs +++ b/crates/executor/src/class.rs @@ -1,5 +1,8 @@ use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; -use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedOpaqueClassDefinition}; +use pathfinder_common::class_definition::{ + SerializedCasmDefinition, + SerializedOpaqueClassDefinition, +}; pub fn parse_deprecated_class_definition( definition: SerializedOpaqueClassDefinition, diff --git a/crates/executor/src/state_reader/storage_adapter.rs b/crates/executor/src/state_reader/storage_adapter.rs index 0f140f7186..9c6d19c388 100644 --- a/crates/executor/src/state_reader/storage_adapter.rs +++ b/crates/executor/src/state_reader/storage_adapter.rs @@ -1,6 +1,9 @@ use blockifier::blockifier::config::TransactionExecutorConfig; use blockifier::state::errors::StateError; -use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedOpaqueClassDefinition}; +use pathfinder_common::class_definition::{ + SerializedCasmDefinition, + SerializedOpaqueClassDefinition, +}; use pathfinder_common::{ BlockHash, BlockId, @@ -18,7 +21,8 @@ pub mod rc; // Keep clippy happy type ClassDefinitionAtWithBlockNumber = Option<(BlockNumber, SerializedOpaqueClassDefinition)>; -type ClassDefinitionWithBlockNumber = Option<(Option, SerializedOpaqueClassDefinition)>; +type ClassDefinitionWithBlockNumber = + Option<(Option, SerializedOpaqueClassDefinition)>; pub trait StorageAdapter { fn transaction_executor_config(&self) -> TransactionExecutorConfig; diff --git a/crates/feeder-gateway/src/main.rs b/crates/feeder-gateway/src/main.rs index 52b905588f..8e8aa9255c 100644 --- a/crates/feeder-gateway/src/main.rs +++ b/crates/feeder-gateway/src/main.rs @@ -37,7 +37,10 @@ use pathfinder_block_commitments::{ calculate_receipt_commitment, calculate_transaction_commitment, }; -use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedOpaqueClassDefinition}; +use pathfinder_common::class_definition::{ + SerializedCasmDefinition, + SerializedOpaqueClassDefinition, +}; use pathfinder_common::integration_testing::debug_create_port_marker_file; use pathfinder_common::prelude::*; use pathfinder_common::state_update::ContractClassUpdate; diff --git a/crates/gateway-client/src/lib.rs b/crates/gateway-client/src/lib.rs index 0e9ae26cc1..da01846337 100644 --- a/crates/gateway-client/src/lib.rs +++ b/crates/gateway-client/src/lib.rs @@ -5,7 +5,10 @@ use std::sync::{Arc, RwLock}; use std::time::Duration; use anyhow::Context; -use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedOpaqueClassDefinition}; +use pathfinder_common::class_definition::{ + SerializedCasmDefinition, + SerializedOpaqueClassDefinition, +}; use pathfinder_common::prelude::*; use reqwest::Url; use starknet_gateway_types::error::SequencerError; diff --git a/crates/pathfinder/examples/recompute_casm_class_hashes.rs b/crates/pathfinder/examples/recompute_casm_class_hashes.rs index 2f7384ac55..3836d1731b 100644 --- a/crates/pathfinder/examples/recompute_casm_class_hashes.rs +++ b/crates/pathfinder/examples/recompute_casm_class_hashes.rs @@ -45,7 +45,9 @@ fn main() -> Result<(), Box> { .map_err(|e| rusqlite::types::FromSqlError::Other(e.into())) .unwrap(); let computed_hash = pathfinder_compiler::casm_class_hash_v2( - &pathfinder_common::class_definition::SerializedCasmDefinition::from_bytes(definition), + &pathfinder_common::class_definition::SerializedCasmDefinition::from_bytes( + definition, + ), ) .unwrap(); println!( diff --git a/crates/pathfinder/src/state/sync/l2.rs b/crates/pathfinder/src/state/sync/l2.rs index 9c7471af0f..27171f420e 100644 --- a/crates/pathfinder/src/state/sync/l2.rs +++ b/crates/pathfinder/src/state/sync/l2.rs @@ -1855,18 +1855,15 @@ mod tests { }) } - static CONTRACT0_DEF: LazyLock = - LazyLock::new(|| { - SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}0{DEF1}").into_bytes()) - }); - static CONTRACT0_DEF_V2: LazyLock = - LazyLock::new(|| { - SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}0 v2{DEF1}").into_bytes()) - }); - static CONTRACT1_DEF: LazyLock = - LazyLock::new(|| { - SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}1{DEF1}").into_bytes()) - }); + static CONTRACT0_DEF: LazyLock = LazyLock::new(|| { + SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}0{DEF1}").into_bytes()) + }); + static CONTRACT0_DEF_V2: LazyLock = LazyLock::new(|| { + SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}0 v2{DEF1}").into_bytes()) + }); + static CONTRACT1_DEF: LazyLock = LazyLock::new(|| { + SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}1{DEF1}").into_bytes()) + }); static BLOCK0: LazyLock = LazyLock::new(|| reply::Block { block_hash: BLOCK0_HASH, diff --git a/crates/pathfinder/src/state/sync/repair.rs b/crates/pathfinder/src/state/sync/repair.rs index 8cb193aee1..a7ae76fabf 100644 --- a/crates/pathfinder/src/state/sync/repair.rs +++ b/crates/pathfinder/src/state/sync/repair.rs @@ -218,7 +218,10 @@ mod tests { let mut db = storage.connection().unwrap(); let tx = db.transaction().unwrap(); let stored = tx.class_definition(hash).unwrap(); - assert_eq!(stored, Some(SerializedOpaqueClassDefinition::from(definition))); + assert_eq!( + stored, + Some(SerializedOpaqueClassDefinition::from(definition)) + ); } /// Cairo 0 classes can have a mismatch between the declared hash and the diff --git a/crates/pathfinder/src/sync/checkpoint.rs b/crates/pathfinder/src/sync/checkpoint.rs index b8d44750f3..05eee92dcf 100644 --- a/crates/pathfinder/src/sync/checkpoint.rs +++ b/crates/pathfinder/src/sync/checkpoint.rs @@ -1536,7 +1536,10 @@ mod tests { ]); let expected_defs = [ - (cairo_hash, SerializedOpaqueClassDefinition::from_slice(CAIRO)), + ( + cairo_hash, + SerializedOpaqueClassDefinition::from_slice(CAIRO), + ), ( ClassHash(sierra0_hash.0), SerializedOpaqueClassDefinition::from_slice(SIERRA0), diff --git a/crates/rpc/src/executor.rs b/crates/rpc/src/executor.rs index b097af7925..bb311e5e6b 100644 --- a/crates/rpc/src/executor.rs +++ b/crates/rpc/src/executor.rs @@ -1,5 +1,8 @@ use anyhow::Context; -use pathfinder_common::class_definition::{SerializedOpaqueClassDefinition, SerializedSierraDefinition}; +use pathfinder_common::class_definition::{ + SerializedOpaqueClassDefinition, + SerializedSierraDefinition, +}; use pathfinder_common::transaction::TransactionVariant; use pathfinder_common::{BlockNumber, ChainId, StarknetVersion}; use pathfinder_executor::types::to_starknet_api_transaction; @@ -123,9 +126,10 @@ pub(crate) fn map_broadcasted_transaction( BroadcastedTransaction::Declare(BroadcastedDeclareTransaction::V2(tx)) => { let sierra_version = SierraVersion::extract_from_program(&tx.contract_class.sierra_program)?; - let sierra_definition = - SerializedSierraDefinition::from_bytes(serde_json::to_vec(&tx.contract_class) - .context("Serializing Sierra class definition")?); + let sierra_definition = SerializedSierraDefinition::from_bytes( + serde_json::to_vec(&tx.contract_class) + .context("Serializing Sierra class definition")?, + ); let casm_contract_definition = pathfinder_compiler::compile_sierra_to_casm( &sierra_definition, compiler_resource_limits, @@ -148,9 +152,10 @@ pub(crate) fn map_broadcasted_transaction( BroadcastedTransaction::Declare(BroadcastedDeclareTransaction::V3(tx)) => { let sierra_version = SierraVersion::extract_from_program(&tx.contract_class.sierra_program)?; - let sierra_definition = - SerializedSierraDefinition::from_bytes(serde_json::to_vec(&tx.contract_class) - .context("Serializing Sierra class definition")?); + let sierra_definition = SerializedSierraDefinition::from_bytes( + serde_json::to_vec(&tx.contract_class) + .context("Serializing Sierra class definition")?, + ); let casm_contract_definition = pathfinder_compiler::compile_sierra_to_casm( &sierra_definition, compiler_resource_limits, diff --git a/crates/rpc/src/method/add_declare_transaction.rs b/crates/rpc/src/method/add_declare_transaction.rs index bf8591cea1..e5adf2b648 100644 --- a/crates/rpc/src/method/add_declare_transaction.rs +++ b/crates/rpc/src/method/add_declare_transaction.rs @@ -486,10 +486,12 @@ mod tests { use crate::types::ContractClass; pub static CONTRACT_CLASS: LazyLock = LazyLock::new(|| { - ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(CONTRACT_DEFINITION)) - .unwrap() - .as_cairo() - .unwrap() + ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice( + CONTRACT_DEFINITION, + )) + .unwrap() + .as_cairo() + .unwrap() }); pub static CONTRACT_CLASS_WITH_INVALID_PRIME: LazyLock = @@ -503,25 +505,31 @@ mod tests { .get_mut("prime") .unwrap() = serde_json::json!("0x1"); let definition = serde_json::to_vec(&definition).unwrap(); - ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(&definition)) - .unwrap() - .as_cairo() - .unwrap() + ContractClass::try_from_serialized_definition( + &SerializedOpaqueClassDefinition::from_slice(&definition), + ) + .unwrap() + .as_cairo() + .unwrap() }); pub static SIERRA_CLASS: LazyLock = LazyLock::new(|| { - ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(CAIRO_2_0_0_STACK_OVERFLOW)) - .unwrap() - .as_sierra() - .unwrap() + ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice( + CAIRO_2_0_0_STACK_OVERFLOW, + )) + .unwrap() + .as_sierra() + .unwrap() }); pub static INTEGRATION_SIERRA_CLASS: LazyLock = LazyLock::new(|| { - ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(include_bytes!( + ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice( + include_bytes!( "../../fixtures/contracts/\ integration_class_0x5ae9d09292a50ed48c5930904c880dab56e85b825022a7d689cfc9e65e01ee7.\ json" - ))) + ), + )) .unwrap() .as_sierra() .unwrap() diff --git a/crates/rpc/src/method/estimate_fee.rs b/crates/rpc/src/method/estimate_fee.rs index 1c0ac05c95..6344a5b075 100644 --- a/crates/rpc/src/method/estimate_fee.rs +++ b/crates/rpc/src/method/estimate_fee.rs @@ -266,11 +266,12 @@ mod tests { let casm_hash = casm_hash!("0x069032ff71f77284e1a0864a573007108ca5cc08089416af50f03260f5d6d4d8"); - let contract_class: SierraContractClass = - ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(sierra_definition)) - .unwrap() - .as_sierra() - .unwrap(); + let contract_class: SierraContractClass = ContractClass::try_from_serialized_definition( + &SerializedOpaqueClassDefinition::from_slice(sierra_definition), + ) + .unwrap() + .as_sierra() + .unwrap(); assert_eq!(contract_class.class_hash().unwrap().hash(), sierra_hash); @@ -605,11 +606,12 @@ mod tests { let casm_hash = casm_hash!("0x02F58B23F7D98FF076AE59C08125AAFFD6DECCF1A7E97378D1A303B1A4223989"); - let contract_class: SierraContractClass = - ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(sierra_definition)) - .unwrap() - .as_sierra() - .unwrap(); + let contract_class: SierraContractClass = ContractClass::try_from_serialized_definition( + &SerializedOpaqueClassDefinition::from_slice(sierra_definition), + ) + .unwrap() + .as_sierra() + .unwrap(); self::assert_eq!(contract_class.class_hash().unwrap().hash(), sierra_hash); @@ -641,11 +643,12 @@ mod tests { let casm_hash = casm_hash!("0x138cd11c6de707426665bd8b0425d7411bb8dc5cbee15867025007a933b3379"); - let contract_class: SierraContractClass = - ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(sierra_definition)) - .unwrap() - .as_sierra() - .unwrap(); + let contract_class: SierraContractClass = ContractClass::try_from_serialized_definition( + &SerializedOpaqueClassDefinition::from_slice(sierra_definition), + ) + .unwrap() + .as_sierra() + .unwrap(); self::assert_eq!(contract_class.class_hash().unwrap().hash(), sierra_hash); diff --git a/crates/rpc/src/method/simulate_transactions.rs b/crates/rpc/src/method/simulate_transactions.rs index 9d20871d3e..4db5eaeb96 100644 --- a/crates/rpc/src/method/simulate_transactions.rs +++ b/crates/rpc/src/method/simulate_transactions.rs @@ -718,10 +718,12 @@ pub(crate) mod tests { pub const CAIRO0_HASH: ClassHash = class_hash!("02c52e7084728572ea940b4df708a2684677c19fa6296de2ea7ba5327e3a84ef"); - let contract_class = crate::types::ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(CAIRO0_DEFINITION)) - .unwrap() - .as_cairo() - .unwrap(); + let contract_class = crate::types::ContractClass::try_from_serialized_definition( + &SerializedOpaqueClassDefinition::from_slice(CAIRO0_DEFINITION), + ) + .unwrap() + .as_cairo() + .unwrap(); assert_eq!(contract_class.class_hash().unwrap().hash(), CAIRO0_HASH); @@ -929,11 +931,12 @@ pub(crate) mod tests { }; pub fn declare(account_contract_address: ContractAddress) -> BroadcastedTransaction { - let contract_class = - crate::types::ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(SIERRA_DEFINITION)) - .unwrap() - .as_sierra() - .unwrap(); + let contract_class = crate::types::ContractClass::try_from_serialized_definition( + &SerializedOpaqueClassDefinition::from_slice(SIERRA_DEFINITION), + ) + .unwrap() + .as_sierra() + .unwrap(); assert_eq!(contract_class.class_hash().unwrap().hash(), SIERRA_HASH); @@ -955,11 +958,12 @@ pub(crate) mod tests { ) -> (BroadcastedTransaction, ClassHash) { let contract_definition = include_bytes!("../../fixtures/contracts/libfuncs_coverage.json"); - let contract_class = - crate::types::ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(contract_definition)) - .unwrap() - .as_sierra() - .unwrap(); + let contract_class = crate::types::ContractClass::try_from_serialized_definition( + &SerializedOpaqueClassDefinition::from_slice(contract_definition), + ) + .unwrap() + .as_sierra() + .unwrap(); let contract_hash = contract_class.class_hash().unwrap().hash(); let declare_tx = BroadcastedTransaction::Declare( BroadcastedDeclareTransaction::V3(BroadcastedDeclareTransactionV3 { diff --git a/crates/rpc/src/types/class.rs b/crates/rpc/src/types/class.rs index 4f6175a7e7..255f06d244 100644 --- a/crates/rpc/src/types/class.rs +++ b/crates/rpc/src/types/class.rs @@ -23,8 +23,9 @@ impl ContractClass { pub fn try_from_serialized_definition( serialized_definition: &SerializedOpaqueClassDefinition, ) -> anyhow::Result { - let mut json = serde_json::from_slice::(serialized_definition.as_bytes()) - .context("Parsing json")?; + let mut json = + serde_json::from_slice::(serialized_definition.as_bytes()) + .context("Parsing json")?; let json_obj = json .as_object_mut() .context("Class definition is not a json object")?; @@ -232,7 +233,10 @@ pub mod cairo { impl CairoContractClass { pub fn class_hash(&self) -> anyhow::Result { let serialized = self.serialize_to_json()?; - let definition = pathfinder_common::class_definition::SerializedOpaqueClassDefinition::from_bytes(serialized); + let definition = + pathfinder_common::class_definition::SerializedOpaqueClassDefinition::from_bytes( + serialized, + ); compute_class_hash(definition) .map(|(hash, _)| hash) @@ -694,7 +698,10 @@ pub mod sierra { impl SierraContractClass { pub fn class_hash(&self) -> anyhow::Result { let definition = serde_json::to_vec(self)?; - let definition = pathfinder_common::class_definition::SerializedOpaqueClassDefinition::from_bytes(definition); + let definition = + pathfinder_common::class_definition::SerializedOpaqueClassDefinition::from_bytes( + definition, + ); compute_class_hash(definition).map(|(hash, _)| hash) } } @@ -797,9 +804,10 @@ mod tests { #[test] fn compute_sierra_class_hash() { - let (class_hash, _) = - compute_class_hash(SerializedOpaqueClassDefinition::from_slice(CAIRO_0_11_SIERRA)) - .unwrap(); + let (class_hash, _) = compute_class_hash(SerializedOpaqueClassDefinition::from_slice( + CAIRO_0_11_SIERRA, + )) + .unwrap(); let class = ContractClass::try_from_serialized_definition( &SerializedOpaqueClassDefinition::from_slice(CAIRO_0_11_SIERRA), @@ -810,9 +818,10 @@ mod tests { #[test] fn compute_cairo_class_hash() { - let (class_hash, _) = - compute_class_hash(SerializedOpaqueClassDefinition::from_slice(CONTRACT_DEFINITION)) - .unwrap(); + let (class_hash, _) = compute_class_hash(SerializedOpaqueClassDefinition::from_slice( + CONTRACT_DEFINITION, + )) + .unwrap(); let class = ContractClass::try_from_serialized_definition( &SerializedOpaqueClassDefinition::from_slice(CONTRACT_DEFINITION), @@ -860,7 +869,10 @@ mod tests { fn parse_deprecated_class_definition_with_debug_info() { let definition = include_bytes!("../../fixtures/contracts/cairo0_open_zeppelin_class.json"); - let class = ContractClass::try_from_serialized_definition(&SerializedOpaqueClassDefinition::from_slice(definition)).unwrap(); + let class = ContractClass::try_from_serialized_definition( + &SerializedOpaqueClassDefinition::from_slice(definition), + ) + .unwrap(); // this step involves parsing the full program including debug info class.as_cairo().unwrap().serialize_to_json().unwrap(); diff --git a/crates/storage/src/connection/class.rs b/crates/storage/src/connection/class.rs index 1f373a078e..9997e8f03c 100644 --- a/crates/storage/src/connection/class.rs +++ b/crates/storage/src/connection/class.rs @@ -676,7 +676,9 @@ mod tests { let result = tx.class_definition(class_hash).unwrap(); assert_eq!( result, - Some(SerializedOpaqueClassDefinition::from_slice(sierra_definition)) + Some(SerializedOpaqueClassDefinition::from_slice( + sierra_definition + )) ); let result = tx.casm_definition(class_hash).unwrap(); diff --git a/crates/storage/src/fake.rs b/crates/storage/src/fake.rs index 7bd50cdb07..2b92505c2c 100644 --- a/crates/storage/src/fake.rs +++ b/crates/storage/src/fake.rs @@ -348,7 +348,10 @@ pub mod generate { .unwrap(); let def = SerializedOpaqueClassDefinition::from_bytes(def); let (hash, _) = compute_class_hash(def.clone()).unwrap(); - (hash.hash(), SerializedCairoDefinition::from_bytes(def.into_bytes())) + ( + hash.hash(), + SerializedCairoDefinition::from_bytes(def.into_bytes()), + ) }) .collect::>(); let sierra_defs = (0..num_sierra_classes) From a87f0c5c24bafafa1a65f0367eb4ab3d4caf2100 Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Thu, 16 Apr 2026 10:39:21 +0200 Subject: [PATCH 6/8] fixup: cairo-native build failure, clippy --- crates/class-hash/src/lib.rs | 6 +++--- crates/executor/src/state_reader/native.rs | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/crates/class-hash/src/lib.rs b/crates/class-hash/src/lib.rs index 3f45b239a2..c5e81e4f8f 100644 --- a/crates/class-hash/src/lib.rs +++ b/crates/class-hash/src/lib.rs @@ -885,9 +885,9 @@ pub mod json { // Known contract which triggered a hash mismatch failure. let extract = tokio::task::spawn_blocking(move || -> anyhow::Result<_> { - Ok(compute_class_hash( - SerializedOpaqueClassDefinition::from_slice(CAIRO_0_8_NEW_ATTRIBUTES), - )?) + compute_class_hash(SerializedOpaqueClassDefinition::from_slice( + CAIRO_0_8_NEW_ATTRIBUTES, + )) }); let (calculated_hash, _) = extract.await.unwrap().unwrap(); diff --git a/crates/executor/src/state_reader/native.rs b/crates/executor/src/state_reader/native.rs index 0f0ce241da..91f16f4296 100644 --- a/crates/executor/src/state_reader/native.rs +++ b/crates/executor/src/state_reader/native.rs @@ -6,7 +6,10 @@ use blockifier::state::errors::StateError; use cached::{Cached, SizedCache}; use cairo_native::executor::AotContractExecutor; use cairo_vm::types::errors::program_errors::ProgramError; -use pathfinder_common::class_definition::{SerializedCasmDefinition, SerializedClassDefinition}; +use pathfinder_common::class_definition::{ + SerializedCasmDefinition, + SerializedOpaqueClassDefinition, +}; use pathfinder_common::ClassHash; use starknet_api::contract_class::SierraVersion; use tokio_util::sync::CancellationToken; @@ -14,7 +17,7 @@ use tokio_util::sync::CancellationToken; struct CompilerInput { class_hash: ClassHash, sierra_version: SierraVersion, - class_definition: SerializedClassDefinition, + class_definition: SerializedOpaqueClassDefinition, casm_definition: SerializedCasmDefinition, } @@ -54,7 +57,7 @@ impl NativeClassCache { &self, class_hash: ClassHash, sierra_version: SierraVersion, - class_definition: SerializedClassDefinition, + class_definition: SerializedOpaqueClassDefinition, casm_definition: SerializedCasmDefinition, ) -> Option { let mut locked = self.cache.lock().unwrap(); From 592a4f2a7a991a698f5a06c3b30dd3550d211df1 Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Thu, 16 Apr 2026 10:40:56 +0200 Subject: [PATCH 7/8] refactor: derive Dummy --- crates/common/src/class_definition.rs | 36 +++------------------------ 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/crates/common/src/class_definition.rs b/crates/common/src/class_definition.rs index c71e2d4e87..f47400a9c0 100644 --- a/crates/common/src/class_definition.rs +++ b/crates/common/src/class_definition.rs @@ -12,18 +12,18 @@ use crate::{ByteCodeOffset, EntryPoint}; pub const CLASS_DEFINITION_MAX_ALLOWED_SIZE: u64 = 4 * 1024 * 1024; -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)] pub struct SerializedSierraDefinition(Vec); -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)] pub struct SerializedCasmDefinition(Vec); -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)] pub struct SerializedCairoDefinition(Vec); /// Carries the definition of a serialized contract class, either Sierra or /// Cairo. The caller does not care which class definition it is. -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)] pub struct SerializedOpaqueClassDefinition(Vec); /// Carries the definition of a serialized contract class, either Sierra or @@ -298,31 +298,3 @@ impl From for SerializedOpaqueClassDefinition { Self::from_bytes(d.into_bytes()) } } - -// TODO derive? -impl Dummy for SerializedSierraDefinition { - fn dummy_with_rng(_: &T, rng: &mut R) -> Self { - Self(Faker.fake_with_rng(rng)) - } -} - -// TODO derive? -impl Dummy for SerializedCasmDefinition { - fn dummy_with_rng(_: &T, rng: &mut R) -> Self { - Self(Faker.fake_with_rng(rng)) - } -} - -// TODO derive? -impl Dummy for SerializedCairoDefinition { - fn dummy_with_rng(_: &T, rng: &mut R) -> Self { - Self(Faker.fake_with_rng(rng)) - } -} - -// TODO derive? -impl Dummy for SerializedOpaqueClassDefinition { - fn dummy_with_rng(_: &T, rng: &mut R) -> Self { - Self(Faker.fake_with_rng(rng)) - } -} From 3de8656813a818a828f439b6c4b4c593eb20ebeb Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Thu, 16 Apr 2026 11:32:10 +0200 Subject: [PATCH 8/8] fixup: use reinterpreted output from compute_class_hash in fake storage --- crates/storage/src/fake.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/crates/storage/src/fake.rs b/crates/storage/src/fake.rs index 2b92505c2c..83e5eb10b4 100644 --- a/crates/storage/src/fake.rs +++ b/crates/storage/src/fake.rs @@ -220,11 +220,8 @@ pub fn fill(storage: &Storage, blocks: &[Block], update_tries: Option>(); let sierra_defs = (0..num_sierra_classes) @@ -361,9 +358,11 @@ pub mod generate { ) .unwrap(); let def = SerializedOpaqueClassDefinition::from_bytes(def); - let (hash, _) = compute_class_hash(def.clone()).unwrap(); + let (hash, sierra_def) = compute_class_hash(def).unwrap(); + let SerializedClassDefinition::Sierra(sierra_def) = sierra_def else { + panic!("Expected a Sierra class definition"); + }; let hash = SierraHash(hash.hash().0); - let sierra_def = SerializedSierraDefinition::from_bytes(def.into_bytes()); let casm_def = SerializedCasmDefinition::from_bytes( Faker.fake_with_rng::(rng).into_bytes(), );