From a5bec9446d11adbf60adaf140a8366b84b3d385c Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Tue, 21 Apr 2026 19:16:57 +0200 Subject: [PATCH 1/2] refactor(class_definition): use vec and slice in favor of bytes in method names --- Cargo.lock | 1 + crates/class-hash/src/lib.rs | 12 +-- crates/common/Cargo.toml | 6 +- crates/common/src/casm_class.rs | 2 +- crates/common/src/class_definition.rs | 93 ++++++++++++------- crates/compiler/src/lib.rs | 18 ++-- crates/executor/src/class.rs | 4 +- crates/executor/src/state_reader.rs | 6 +- crates/executor/src/state_reader/native.rs | 4 +- crates/feeder-gateway/src/main.rs | 4 +- crates/gateway-client/src/lib.rs | 4 +- crates/p2p/src/sync/client/conv.rs | 4 +- .../pathfinder/examples/compute_class_hash.rs | 2 +- .../examples/recompute_casm_class_hashes.rs | 2 +- crates/pathfinder/src/bin/pathfinder/main.rs | 4 +- crates/pathfinder/src/devnet/class.rs | 2 +- .../src/p2p_network/sync/sync_handlers.rs | 12 +-- crates/pathfinder/src/state/sync/l2.rs | 6 +- crates/pathfinder/src/sync/checkpoint.rs | 2 +- .../pathfinder/src/sync/class_definitions.rs | 4 +- crates/rpc/src/executor.rs | 12 +-- crates/rpc/src/method/call.rs | 2 +- crates/rpc/src/types/class.rs | 8 +- crates/storage/src/connection/class.rs | 22 ++--- crates/storage/src/fake.rs | 6 +- crates/storage/src/schema/revision_0076.rs | 2 +- crates/validator/src/lib.rs | 2 +- 27 files changed, 138 insertions(+), 108 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 131e3785b9..1d9919509d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8462,6 +8462,7 @@ dependencies = [ "anyhow", "base64 0.22.1", "bitvec", + "bytes", "fake", "metrics", "num-bigint 0.4.6", diff --git a/crates/class-hash/src/lib.rs b/crates/class-hash/src/lib.rs index 4750834526..db8380641d 100644 --- a/crates/class-hash/src/lib.rs +++ b/crates/class-hash/src/lib.rs @@ -109,8 +109,8 @@ 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. - SerializedClassDefinition::Sierra(SerializedSierraDefinition::from_bytes( - serialized_definition.into_bytes(), + SerializedClassDefinition::Sierra(SerializedSierraDefinition::from_vec( + serialized_definition.into_vec(), )), ) }), @@ -122,8 +122,8 @@ 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. - SerializedClassDefinition::Cairo(SerializedCairoDefinition::from_bytes( - serialized_definition.into_bytes(), + SerializedClassDefinition::Cairo(SerializedCairoDefinition::from_vec( + serialized_definition.into_vec(), )), ) }), @@ -166,11 +166,11 @@ pub fn compute_cairo_hinted_class_hash( fn parse_contract_definition( serialized_definition: &SerializedOpaqueClassDefinition, ) -> serde_json::Result> { - serde_json::from_slice::>(serialized_definition.as_bytes()) + serde_json::from_slice::>(serialized_definition.as_slice()) .map(json::ContractDefinition::Sierra) .or_else(|_| { serde_json::from_slice::>( - serialized_definition.as_bytes(), + serialized_definition.as_slice(), ) .map(json::ContractDefinition::Cairo) }) diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 29c0c104c3..40b489f368 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -23,6 +23,7 @@ full-serde = [] anyhow = { workspace = true } base64 = { workspace = true } bitvec = { workspace = true } +bytes = { workspace = true } fake = { workspace = true, features = ["derive"] } metrics = { workspace = true } num-bigint = { workspace = true } @@ -34,7 +35,10 @@ pathfinder-tagged-debug-derive = { version = "0.1.0", path = "../tagged-debug-de primitive-types = { workspace = true, features = ["serde"] } rand = { workspace = true } serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true, features = ["arbitrary_precision", "raw_value"] } +serde_json = { workspace = true, features = [ + "arbitrary_precision", + "raw_value", +] } serde_with = { workspace = true } sha3 = { workspace = true } thiserror = { workspace = true } diff --git a/crates/common/src/casm_class.rs b/crates/common/src/casm_class.rs index d4db5dcaf1..043e4f89f8 100644 --- a/crates/common/src/casm_class.rs +++ b/crates/common/src/casm_class.rs @@ -94,6 +94,6 @@ impl CasmContractClass { pub fn from_serialized_def( definition: &crate::class_definition::SerializedCasmDefinition, ) -> Result { - serde_json::from_slice(definition.as_bytes()) + serde_json::from_slice(definition.as_slice()) } } diff --git a/crates/common/src/class_definition.rs b/crates/common/src/class_definition.rs index f47400a9c0..6d9b6400df 100644 --- a/crates/common/src/class_definition.rs +++ b/crates/common/src/class_definition.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use std::fmt; +use bytes::Bytes; use fake::{Dummy, Fake, Faker}; use pathfinder_crypto::Felt; use rand::Rng; @@ -12,19 +13,19 @@ use crate::{ByteCodeOffset, EntryPoint}; pub const CLASS_DEFINITION_MAX_ALLOWED_SIZE: u64 = 4 * 1024 * 1024; -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)] -pub struct SerializedSierraDefinition(Vec); +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +pub struct SerializedSierraDefinition(Bytes); -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)] -pub struct SerializedCasmDefinition(Vec); +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +pub struct SerializedCasmDefinition(Bytes); -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)] -pub struct SerializedCairoDefinition(Vec); +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +pub struct SerializedCairoDefinition(Bytes); /// 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, Dummy)] -pub struct SerializedOpaqueClassDefinition(Vec); +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +pub struct SerializedOpaqueClassDefinition(Bytes); /// Carries the definition of a serialized contract class, either Sierra or /// Cairo. @@ -214,73 +215,73 @@ pub struct SelectorAndFunctionIndex { } impl SerializedSierraDefinition { - pub fn from_bytes(bytes: Vec) -> Self { - Self(bytes) + pub fn from_vec(bytes: Vec) -> Self { + Self(Bytes::from_owner(bytes)) } pub fn from_slice(bytes: &[u8]) -> Self { - Self(bytes.to_vec()) + Self(Bytes::copy_from_slice(bytes)) } - pub fn into_bytes(self) -> Vec { - self.0 + pub fn into_vec(self) -> Vec { + self.0.into() } - pub fn as_bytes(&self) -> &[u8] { + pub fn as_slice(&self) -> &[u8] { &self.0 } } impl SerializedCasmDefinition { - pub fn from_bytes(bytes: Vec) -> Self { - Self(bytes) + pub fn from_vec(bytes: Vec) -> Self { + Self(Bytes::from_owner(bytes)) } pub fn from_slice(bytes: &[u8]) -> Self { - Self(bytes.to_vec()) + Self(Bytes::copy_from_slice(bytes)) } - pub fn into_bytes(self) -> Vec { - self.0 + pub fn into_vec(self) -> Vec { + self.0.into() } - pub fn as_bytes(&self) -> &[u8] { + pub fn as_slice(&self) -> &[u8] { &self.0 } } impl SerializedCairoDefinition { - pub fn from_bytes(bytes: Vec) -> Self { - Self(bytes) + pub fn from_vec(bytes: Vec) -> Self { + Self(Bytes::from_owner(bytes)) } pub fn from_slice(bytes: &[u8]) -> Self { - Self(bytes.to_vec()) + Self(Bytes::copy_from_slice(bytes)) } - pub fn into_bytes(self) -> Vec { - self.0 + pub fn into_vec(self) -> Vec { + self.0.into() } - pub fn as_bytes(&self) -> &[u8] { + pub fn as_slice(&self) -> &[u8] { &self.0 } } impl SerializedOpaqueClassDefinition { - pub fn from_bytes(bytes: Vec) -> Self { - Self(bytes) + pub fn from_vec(bytes: Vec) -> Self { + Self(Bytes::from_owner(bytes)) } pub fn from_slice(bytes: &[u8]) -> Self { - Self(bytes.to_vec()) + Self(Bytes::copy_from_slice(bytes)) } - pub fn into_bytes(self) -> Vec { - self.0 + pub fn into_vec(self) -> Vec { + self.0.into() } - pub fn as_bytes(&self) -> &[u8] { + pub fn as_slice(&self) -> &[u8] { &self.0 } } @@ -288,13 +289,37 @@ impl SerializedOpaqueClassDefinition { /// We can use `From` because this is always safe. impl From for SerializedOpaqueClassDefinition { fn from(d: SerializedSierraDefinition) -> Self { - Self::from_bytes(d.into_bytes()) + Self::from_vec(d.into_vec()) } } /// We can use `From` because this is always safe. impl From for SerializedOpaqueClassDefinition { fn from(d: SerializedCairoDefinition) -> Self { - Self::from_bytes(d.into_bytes()) + Self::from_vec(d.into_vec()) + } +} + +impl Dummy for SerializedSierraDefinition { + fn dummy_with_rng(_: &T, rng: &mut R) -> Self { + Self(Bytes::from(Faker.fake_with_rng::, R>(rng))) + } +} + +impl Dummy for SerializedCasmDefinition { + fn dummy_with_rng(_: &T, rng: &mut R) -> Self { + Self(Bytes::from(Faker.fake_with_rng::, R>(rng))) + } +} + +impl Dummy for SerializedCairoDefinition { + fn dummy_with_rng(_: &T, rng: &mut R) -> Self { + Self(Bytes::from(Faker.fake_with_rng::, R>(rng))) + } +} + +impl Dummy for SerializedOpaqueClassDefinition { + fn dummy_with_rng(_: &T, rng: &mut R) -> Self { + Self(Bytes::from(Faker.fake_with_rng::, R>(rng))) } } diff --git a/crates/compiler/src/lib.rs b/crates/compiler/src/lib.rs index 723e5517c2..9bdd4f75c3 100644 --- a/crates/compiler/src/lib.rs +++ b/crates/compiler/src/lib.rs @@ -127,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.as_bytes()) + .write_all(sierra_definition.as_slice()) .context("writing Sierra definition to child stdin")?; ch_stdin.flush().context("flushing child stdin")?; } @@ -145,7 +145,7 @@ pub fn compile_sierra_to_casm( ); } - Ok(SerializedCasmDefinition::from_bytes(output.stdout)) + Ok(SerializedCasmDefinition::from_vec(output.stdout)) } /// Compile a Sierra class definition into CASM using an isolated child process. @@ -165,7 +165,7 @@ pub fn compile_sierra_to_casm_deser( .context("serializing Sierra definition") .map(|sierra_definition| { compile_sierra_to_casm( - &class_definition::SerializedSierraDefinition::from_bytes(sierra_definition), + &class_definition::SerializedSierraDefinition::from_vec(sierra_definition), resource_limits, blockifier_libfuncs, ) @@ -317,7 +317,7 @@ pub fn compile_sierra_to_casm_impl( // 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.as_bytes()) + serde_json::from_slice::>(sierra_definition.as_slice()) .context("Parsing Sierra class") .map(|sierra_class| compile_sierra_to_casm_deser_impl(sierra_class, blockifier_libfuncs))? .context("Compiling Sierra to CASM") @@ -385,7 +385,7 @@ fn parse_sierra_version(program: &[Felt]) -> anyhow::Result { /// /// Uses the _latest_ compiler for the parsing and starknet_api for the hashing. pub fn casm_class_hash_v2(casm_definition: &SerializedCasmDefinition) -> anyhow::Result { - v2::casm_class_hash_v2(casm_definition.as_bytes()) + v2::casm_class_hash_v2(casm_definition.as_slice()) } mod v1_0_0_alpha6 { @@ -431,7 +431,7 @@ mod v1_0_0_alpha6 { let casm_class = CasmContractClass::from_contract_class(sierra_class, true) .context("Compiling to CASM")?; - Ok(super::SerializedCasmDefinition::from_bytes( + Ok(super::SerializedCasmDefinition::from_vec( serde_json::to_vec(&casm_class)?, )) } @@ -480,7 +480,7 @@ mod v1_0_0_rc0 { let casm_class = CasmContractClass::from_contract_class(sierra_class, true) .context("Compiling to CASM")?; - Ok(super::SerializedCasmDefinition::from_bytes( + Ok(super::SerializedCasmDefinition::from_vec( serde_json::to_vec(&casm_class)?, )) } @@ -529,7 +529,7 @@ mod v1_1_1 { let casm_class = CasmContractClass::from_contract_class(sierra_class, true) .context("Compiling to CASM")?; - Ok(super::SerializedCasmDefinition::from_bytes( + Ok(super::SerializedCasmDefinition::from_vec( serde_json::to_vec(&casm_class)?, )) } @@ -582,7 +582,7 @@ mod v2 { usize::MAX, ) .context("Compiling to CASM")?; - Ok(super::SerializedCasmDefinition::from_bytes( + Ok(super::SerializedCasmDefinition::from_vec( serde_json::to_vec(&casm_class)?, )) } diff --git a/crates/executor/src/class.rs b/crates/executor/src/class.rs index eed4e254c8..3efcddf8ba 100644 --- a/crates/executor/src/class.rs +++ b/crates/executor/src/class.rs @@ -8,7 +8,7 @@ pub fn parse_deprecated_class_definition( definition: SerializedOpaqueClassDefinition, ) -> anyhow::Result { let class: starknet_api::deprecated_contract_class::ContractClass = - serde_json::from_slice(definition.as_bytes())?; + serde_json::from_slice(definition.as_slice())?; Ok(starknet_api::contract_class::ContractClass::V0(class)) } @@ -17,7 +17,7 @@ pub fn parse_casm_definition( casm_definition: SerializedCasmDefinition, sierra_version: starknet_api::contract_class::SierraVersion, ) -> anyhow::Result { - let class: CasmContractClass = serde_json::from_slice(casm_definition.as_bytes())?; + let class: CasmContractClass = serde_json::from_slice(casm_definition.as_slice())?; 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 a327cd643b..98e9f706dc 100644 --- a/crates/executor/src/state_reader.rs +++ b/crates/executor/src/state_reader.rs @@ -166,7 +166,7 @@ impl PathfinderStateReader { None => { // No CASM definition means this is a legacy Cairo 0 class. let class_definition = - std::str::from_utf8(class_definition.as_bytes()).map_err(|error| { + std::str::from_utf8(class_definition.as_slice()).map_err(|error| { StateError::StateReadError(format!( "Class definition is not valid UTF-8: {error}" )) @@ -189,7 +189,7 @@ impl PathfinderStateReader { ) -> Result { use cairo_vm::types::errors::program_errors::ProgramError; - let sierra_class: Sierra<'_> = serde_json::from_slice(class_definition.as_bytes()) + let sierra_class: Sierra<'_> = serde_json::from_slice(class_definition.as_slice()) .map_err(|error| StateError::ProgramError(ProgramError::Parse(error)))?; SierraVersion::extract_from_program(&sierra_class.sierra_program).map_err(Into::into) } @@ -199,7 +199,7 @@ fn sierra_class_as_casm( sierra_version: SierraVersion, casm_definition: SerializedCasmDefinition, ) -> Result { - let casm_definition = std::str::from_utf8(casm_definition.as_bytes()).map_err(|error| { + let casm_definition = std::str::from_utf8(casm_definition.as_slice()).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( diff --git a/crates/executor/src/state_reader/native.rs b/crates/executor/src/state_reader/native.rs index 91f16f4296..9ec1f7d456 100644 --- a/crates/executor/src/state_reader/native.rs +++ b/crates/executor/src/state_reader/native.rs @@ -142,7 +142,7 @@ fn sierra_class_as_native( optimization_level: cairo_native::OptLevel, ) -> Result { let mut sierra_definition: serde_json::Value = - serde_json::from_slice(input.class_definition.as_bytes()) + serde_json::from_slice(input.class_definition.as_slice()) .map_err(|e| StateError::ProgramError(ProgramError::Parse(e)))?; let sierra_abi_str = sierra_definition .get("abi") @@ -189,7 +189,7 @@ fn sierra_class_as_native( .map_err(|e| StateError::StateReadError(format!("Error compiling native class: {e}")))?; let casm_definition = - std::str::from_utf8(input.casm_definition.as_bytes()).map_err(|error| { + std::str::from_utf8(input.casm_definition.as_slice()).map_err(|error| { StateError::StateReadError(format!("Class definition is not valid UTF-8: {error}")) })?; diff --git a/crates/feeder-gateway/src/main.rs b/crates/feeder-gateway/src/main.rs index 8e8aa9255c..a7a3fbece2 100644 --- a/crates/feeder-gateway/src/main.rs +++ b/crates/feeder-gateway/src/main.rs @@ -509,7 +509,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.into_bytes()).unwrap(); + let response = warp::http::Response::builder().header("content-type", "application/json").body(class.into_vec()).unwrap(); Result::<_, Infallible>::Ok(response) }, Err(_) => { @@ -550,7 +550,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.into_bytes()).unwrap(); + let response = warp::http::Response::builder().header("content-type", "application/json").body(compiled_class.into_vec()).unwrap(); Result::<_, Infallible>::Ok(response) }, Err(_) => { diff --git a/crates/gateway-client/src/lib.rs b/crates/gateway-client/src/lib.rs index fe6ec8f5d9..f992511467 100644 --- a/crates/gateway-client/src/lib.rs +++ b/crates/gateway-client/src/lib.rs @@ -569,7 +569,7 @@ impl GatewayApi for Client { .retry(self.retry) .get_as_bytes() .await?; - Ok(SerializedOpaqueClassDefinition::from_bytes(bytes.to_vec())) + Ok(SerializedOpaqueClassDefinition::from_vec(bytes.to_vec())) } /// Gets CASM for a particular class hash. @@ -587,7 +587,7 @@ impl GatewayApi for Client { .retry(self.retry) .get_as_bytes() .await?; - Ok(SerializedCasmDefinition::from_bytes(bytes.to_vec())) + Ok(SerializedCasmDefinition::from_vec(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 a5ea6d2a9f..c78cb2fc59 100644 --- a/crates/p2p/src/sync/client/conv.rs +++ b/crates/p2p/src/sync/client/conv.rs @@ -954,7 +954,7 @@ impl TryFromDto for SerializedCairoDefinition { }; let class_def = serde_json::to_vec(&class_def).context("serialize cairo class definition")?; - Ok(Self::from_bytes(class_def)) + Ok(Self::from_vec(class_def)) } } @@ -1017,7 +1017,7 @@ impl TryFromDto for SerializedSierraDefinition { let sierra = serde_json::to_vec(&sierra).context("serialize sierra class definition")?; - Ok(Self::from_bytes(sierra)) + Ok(Self::from_vec(sierra)) } } diff --git a/crates/pathfinder/examples/compute_class_hash.rs b/crates/pathfinder/examples/compute_class_hash.rs index 6d3cb5eda5..ca3a9674c3 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::SerializedOpaqueClassDefinition::from_bytes(s); + pathfinder_common::class_definition::SerializedOpaqueClassDefinition::from_vec(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/examples/recompute_casm_class_hashes.rs b/crates/pathfinder/examples/recompute_casm_class_hashes.rs index b86e29b79b..bbf7ca5e35 100644 --- a/crates/pathfinder/examples/recompute_casm_class_hashes.rs +++ b/crates/pathfinder/examples/recompute_casm_class_hashes.rs @@ -46,7 +46,7 @@ fn main() -> Result<(), Box> { .map_err(|e| rusqlite::types::FromSqlError::Other(e.into())) .unwrap(); let computed_hash = pathfinder_compiler::casm_class_hash_v2( - &SerializedCasmDefinition::from_bytes(definition), + &SerializedCasmDefinition::from_vec(definition), ) .unwrap(); println!( diff --git a/crates/pathfinder/src/bin/pathfinder/main.rs b/crates/pathfinder/src/bin/pathfinder/main.rs index ca12d76139..2e726e2a48 100644 --- a/crates/pathfinder/src/bin/pathfinder/main.rs +++ b/crates/pathfinder/src/bin/pathfinder/main.rs @@ -586,7 +586,7 @@ fn compile_main(config: CompileConfig) -> anyhow::Result<()> { std::io::stdin() .read_to_end(&mut sierra_bytes) .context("reading Sierra from stdin")?; - let sierra_definition = SerializedSierraDefinition::from_bytes(sierra_bytes); + let sierra_definition = SerializedSierraDefinition::from_vec(sierra_bytes); let casm = pathfinder_compiler::compile_sierra_to_casm_impl( &sierra_definition, @@ -595,7 +595,7 @@ fn compile_main(config: CompileConfig) -> anyhow::Result<()> { .context("compiling Sierra to CASM")?; std::io::stdout() - .write_all(casm.as_bytes()) + .write_all(casm.as_slice()) .context("writing CASM to stdout") } diff --git a/crates/pathfinder/src/devnet/class.rs b/crates/pathfinder/src/devnet/class.rs index 1e80ae5ce7..4fc7c3492d 100644 --- a/crates/pathfinder/src/devnet/class.rs +++ b/crates/pathfinder/src/devnet/class.rs @@ -106,7 +106,7 @@ pub fn preprocess_sierra( // Re-serialize into a storage-compatible format let sierra_class_ser = - SerializedSierraDefinition::from_bytes(serde_json::to_vec(&sierra_class_def).unwrap()); + SerializedSierraDefinition::from_vec(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 c8060086e3..86373823c8 100644 --- a/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs +++ b/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs @@ -166,12 +166,12 @@ fn get_classes_for_block( .is_sierra(class_hash)? .expect("Class definition exists in storage") { - SerializedClassDefinition::Sierra(SerializedSierraDefinition::from_bytes( - definition.into_bytes(), + SerializedClassDefinition::Sierra(SerializedSierraDefinition::from_vec( + definition.into_vec(), )) } else { - SerializedClassDefinition::Cairo(SerializedCairoDefinition::from_bytes( - definition.into_bytes(), + SerializedClassDefinition::Cairo(SerializedCairoDefinition::from_vec( + definition.into_vec(), )) }; @@ -190,7 +190,7 @@ fn get_classes_for_block( let class: Class = match class_definition { SerializedClassDefinition::Cairo(cairo) => { let cairo_class = - serde_json::from_slice::>(cairo.as_bytes())?; + serde_json::from_slice::>(cairo.as_slice())?; Class::Cairo0 { class: cairo_class.to_dto(), domain: 0, // TODO @@ -199,7 +199,7 @@ fn get_classes_for_block( } SerializedClassDefinition::Sierra(sierra) => { let sierra_class = - serde_json::from_slice::>(sierra.as_bytes())?; + serde_json::from_slice::>(sierra.as_slice())?; Class::Cairo1 { class: sierra_class.to_dto(), diff --git a/crates/pathfinder/src/state/sync/l2.rs b/crates/pathfinder/src/state/sync/l2.rs index 2fe08b45b2..3c3affab53 100644 --- a/crates/pathfinder/src/state/sync/l2.rs +++ b/crates/pathfinder/src/state/sync/l2.rs @@ -1855,13 +1855,13 @@ mod tests { } static CONTRACT0_DEF: LazyLock = LazyLock::new(|| { - SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}0{DEF1}").into_bytes()) + SerializedOpaqueClassDefinition::from_vec(format!("{DEF0}0{DEF1}").into_bytes()) }); static CONTRACT0_DEF_V2: LazyLock = LazyLock::new(|| { - SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}0 v2{DEF1}").into_bytes()) + SerializedOpaqueClassDefinition::from_vec(format!("{DEF0}0 v2{DEF1}").into_bytes()) }); static CONTRACT1_DEF: LazyLock = LazyLock::new(|| { - SerializedOpaqueClassDefinition::from_bytes(format!("{DEF0}1{DEF1}").into_bytes()) + SerializedOpaqueClassDefinition::from_vec(format!("{DEF0}1{DEF1}").into_bytes()) }); static BLOCK0: LazyLock = LazyLock::new(|| reply::Block { diff --git a/crates/pathfinder/src/sync/checkpoint.rs b/crates/pathfinder/src/sync/checkpoint.rs index 05eee92dcf..3dc190519f 100644 --- a/crates/pathfinder/src/sync/checkpoint.rs +++ b/crates/pathfinder/src/sync/checkpoint.rs @@ -1598,7 +1598,7 @@ mod tests { db.casm_definition(ClassHash(SIERRA2_HASH.0)) .unwrap() .unwrap() - .as_bytes() + .as_slice() ) .unwrap()["compiler_version"] .is_string()); diff --git a/crates/pathfinder/src/sync/class_definitions.rs b/crates/pathfinder/src/sync/class_definitions.rs index db08cf9ab6..5bae9e680c 100644 --- a/crates/pathfinder/src/sync/class_definitions.rs +++ b/crates/pathfinder/src/sync/class_definitions.rs @@ -145,7 +145,7 @@ fn verify_layout_impl( hash, } => { let layout = GwClassDefinition::Cairo( - serde_json::from_slice::>(definition.as_bytes()).map_err(|error| { + serde_json::from_slice::>(definition.as_slice()).map_err(|error| { tracing::debug!(%peer, %block_number, %error, "Bad class layout"); SyncError::BadClassLayout(*peer) })?, @@ -163,7 +163,7 @@ fn verify_layout_impl( hash, } => { let layout = GwClassDefinition::Sierra( - serde_json::from_slice::>(sierra_definition.as_bytes()).map_err( + serde_json::from_slice::>(sierra_definition.as_slice()).map_err( |error| { tracing::debug!(%peer, %block_number, %error, "Bad class layout"); SyncError::BadClassLayout(*peer) diff --git a/crates/rpc/src/executor.rs b/crates/rpc/src/executor.rs index 1875fdadd0..f8cd31f605 100644 --- a/crates/rpc/src/executor.rs +++ b/crates/rpc/src/executor.rs @@ -97,7 +97,7 @@ pub(crate) fn map_broadcasted_transaction( .context("Serializing Cairo class to JSON")?; let contract_class = pathfinder_executor::parse_deprecated_class_definition( - SerializedOpaqueClassDefinition::from_bytes(contract_class_json), + SerializedOpaqueClassDefinition::from_vec(contract_class_json), )?; Some(ClassInfo::new( @@ -114,7 +114,7 @@ pub(crate) fn map_broadcasted_transaction( .context("Serializing Cairo class to JSON")?; let contract_class = pathfinder_executor::parse_deprecated_class_definition( - SerializedOpaqueClassDefinition::from_bytes(contract_class_json), + SerializedOpaqueClassDefinition::from_vec(contract_class_json), )?; Some(ClassInfo::new( @@ -127,7 +127,7 @@ 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( + let sierra_definition = SerializedSierraDefinition::from_vec( serde_json::to_vec(&tx.contract_class) .context("Serializing Sierra class definition")?, ); @@ -153,7 +153,7 @@ 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( + let sierra_definition = SerializedSierraDefinition::from_vec( serde_json::to_vec(&tx.contract_class) .context("Serializing Sierra class definition")?, ); @@ -293,7 +293,7 @@ pub fn compose_executor_transaction( .class_definition(tx.class_hash)? .context("Fetching class definition")?; let class_definition: SierraContractClass = - serde_json::from_slice(class_definition.as_bytes()) + serde_json::from_slice(class_definition.as_slice()) .context("Deserializing class definition")?; let sierra_version = SierraVersion::extract_from_program(&class_definition.sierra_program)?; @@ -315,7 +315,7 @@ pub fn compose_executor_transaction( .class_definition(tx.class_hash)? .context("Fetching class definition")?; let class_definition: SierraContractClass = - serde_json::from_slice(class_definition.as_bytes()) + serde_json::from_slice(class_definition.as_slice()) .context("Deserializing class definition")?; let sierra_version = SierraVersion::extract_from_program(&class_definition.sierra_program)?; diff --git a/crates/rpc/src/method/call.rs b/crates/rpc/src/method/call.rs index 186eb2a8a1..374f66cfd1 100644 --- a/crates/rpc/src/method/call.rs +++ b/crates/rpc/src/method/call.rs @@ -716,7 +716,7 @@ mod tests { .unwrap(); tx.insert_sierra_class_definition( &caller_sierra_hash, - &SerializedSierraDefinition::from_bytes(caller_sierra_definition), + &SerializedSierraDefinition::from_vec(caller_sierra_definition), &SerializedCasmDefinition::from_slice(caller_casm_definition), &caller_casm_hash_v2, ) diff --git a/crates/rpc/src/types/class.rs b/crates/rpc/src/types/class.rs index 03aeaeb079..ec75d991b3 100644 --- a/crates/rpc/src/types/class.rs +++ b/crates/rpc/src/types/class.rs @@ -24,7 +24,7 @@ impl ContractClass { serialized_definition: &SerializedOpaqueClassDefinition, ) -> anyhow::Result { let mut json = - serde_json::from_slice::(serialized_definition.as_bytes()) + serde_json::from_slice::(serialized_definition.as_slice()) .context("Parsing json")?; let json_obj = json .as_object_mut() @@ -234,7 +234,7 @@ pub mod cairo { impl CairoContractClass { pub fn class_hash(&self) -> anyhow::Result { let serialized = self.serialize_to_json()?; - let definition = SerializedOpaqueClassDefinition::from_bytes(serialized); + let definition = SerializedOpaqueClassDefinition::from_vec(serialized); compute_class_hash(definition) .map(|(hash, _)| hash) @@ -697,7 +697,7 @@ pub mod sierra { impl SierraContractClass { pub fn class_hash(&self) -> anyhow::Result { let definition = serde_json::to_vec(self)?; - let definition = SerializedOpaqueClassDefinition::from_bytes(definition); + let definition = SerializedOpaqueClassDefinition::from_vec(definition); compute_class_hash(definition).map(|(hash, _)| hash) } } @@ -855,7 +855,7 @@ mod tests { let serialized_definition = contract_class.serialize_to_json().unwrap(); - parse_deprecated_class_definition(SerializedOpaqueClassDefinition::from_bytes( + parse_deprecated_class_definition(SerializedOpaqueClassDefinition::from_vec( serialized_definition, )) .unwrap(); diff --git a/crates/storage/src/connection/class.rs b/crates/storage/src/connection/class.rs index 9997e8f03c..a5f6e0c408 100644 --- a/crates/storage/src/connection/class.rs +++ b/crates/storage/src/connection/class.rs @@ -27,10 +27,10 @@ impl Transaction<'_> { ) -> anyhow::Result<()> { let mut compressor = zstd::bulk::Compressor::new(10).context("Creating zstd compressor")?; let compressed_sierra_definition = compressor - .compress(sierra_definition.as_bytes()) + .compress(sierra_definition.as_slice()) .context("Compressing sierra definition")?; let compressed_casm_definition = compressor - .compress(casm_definition.as_bytes()) + .compress(casm_definition.as_slice()) .context("Compressing casm definition")?; self.inner() @@ -82,10 +82,10 @@ impl Transaction<'_> { ) -> anyhow::Result<()> { let mut compressor = zstd::bulk::Compressor::new(10).context("Creating zstd compressor")?; let compressed_sierra_definition = compressor - .compress(sierra_definition.as_bytes()) + .compress(sierra_definition.as_slice()) .context("Compressing sierra definition")?; let compressed_casm_definition = compressor - .compress(casm_definition.as_bytes()) + .compress(casm_definition.as_slice()) .context("Compressing casm definition")?; self.inner() @@ -128,7 +128,7 @@ impl Transaction<'_> { ) -> anyhow::Result<()> { let mut compressor = zstd::bulk::Compressor::new(10).context("Creating zstd compressor")?; let compressed_definition = compressor - .compress(definition.as_bytes()) + .compress(definition.as_slice()) .context("Compressing cairo definition")?; self.inner() @@ -150,7 +150,7 @@ impl Transaction<'_> { ) -> anyhow::Result<()> { let mut compressor = zstd::bulk::Compressor::new(10).context("Creating zstd compressor")?; let compressed_definition = compressor - .compress(definition.as_bytes()) + .compress(definition.as_slice()) .context("Compressing cairo definition")?; self.inner() @@ -217,7 +217,7 @@ impl Transaction<'_> { Ok(Some(( block_number, - SerializedOpaqueClassDefinition::from_bytes(definition), + SerializedOpaqueClassDefinition::from_vec(definition), ))) } @@ -291,7 +291,7 @@ impl Transaction<'_> { }; let definition = zstd::decode_all(definition.as_slice()).context("Decompressing class definition")?; - let definition = SerializedOpaqueClassDefinition::from_bytes(definition); + let definition = SerializedOpaqueClassDefinition::from_vec(definition); Ok(Some((block_number, definition))) } @@ -319,7 +319,7 @@ impl Transaction<'_> { let definition = zstd::decode_all(definition.as_slice()) .context("Decompressing compiled class definition")?; - Ok(Some(SerializedCasmDefinition::from_bytes(definition))) + Ok(Some(SerializedCasmDefinition::from_vec(definition))) } /// Returns the uncompressed compiled class definition, as well as the block @@ -360,7 +360,7 @@ impl Transaction<'_> { Ok(Some(( block_number, - SerializedCasmDefinition::from_bytes(definition), + SerializedCasmDefinition::from_vec(definition), ))) } @@ -448,7 +448,7 @@ impl Transaction<'_> { Ok(Some(( block_number, - SerializedCasmDefinition::from_bytes(definition), + SerializedCasmDefinition::from_vec(definition), ))) } diff --git a/crates/storage/src/fake.rs b/crates/storage/src/fake.rs index 83e5eb10b4..14a86a87e4 100644 --- a/crates/storage/src/fake.rs +++ b/crates/storage/src/fake.rs @@ -343,7 +343,7 @@ pub mod generate { &Faker.fake_with_rng::, _>(rng), ) .unwrap(); - let def = SerializedOpaqueClassDefinition::from_bytes(def); + let def = SerializedOpaqueClassDefinition::from_vec(def); let (hash, def) = compute_class_hash(def).unwrap(); let SerializedClassDefinition::Cairo(def) = def else { panic!("Expected a Cairo class definition"); @@ -357,13 +357,13 @@ pub mod generate { &Faker.fake_with_rng::, _>(rng), ) .unwrap(); - let def = SerializedOpaqueClassDefinition::from_bytes(def); + let def = SerializedOpaqueClassDefinition::from_vec(def); 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 casm_def = SerializedCasmDefinition::from_bytes( + let casm_def = SerializedCasmDefinition::from_vec( Faker.fake_with_rng::(rng).into_bytes(), ); ( diff --git a/crates/storage/src/schema/revision_0076.rs b/crates/storage/src/schema/revision_0076.rs index 2299fbd5aa..5b08b62f9a 100644 --- a/crates/storage/src/schema/revision_0076.rs +++ b/crates/storage/src/schema/revision_0076.rs @@ -53,7 +53,7 @@ pub(crate) fn migrate(tx: &rusqlite::Transaction<'_>) -> anyhow::Result<()> { .map_err(|e| rusqlite::types::FromSqlError::Other(e.into())) .unwrap(); let computed_hash = pathfinder_compiler::casm_class_hash_v2( - &SerializedCasmDefinition::from_bytes(definition), + &SerializedCasmDefinition::from_vec(definition), ) .unwrap(); (class_hash, computed_hash) diff --git a/crates/validator/src/lib.rs b/crates/validator/src/lib.rs index 4f37659f1d..7b3c0a3c16 100644 --- a/crates/validator/src/lib.rs +++ b/crates/validator/src/lib.rs @@ -1130,7 +1130,7 @@ fn class_info( .collect(), }, }; - let sierra_def = SerializedSierraDefinition::from_bytes(serde_json::to_vec(&definition)?); + let sierra_def = SerializedSierraDefinition::from_vec(serde_json::to_vec(&definition)?); let casm_def = pathfinder_compiler::compile_sierra_to_casm( &sierra_def, compiler_resource_limits, From 4255aa87b0fccbed0637992034c4951dccc239b9 Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Tue, 21 Apr 2026 19:26:54 +0200 Subject: [PATCH 2/2] refactor(class_definition): use conversion to Bytes as a way to reinterpret opaque into sierra or cairo --- crates/class-hash/src/lib.rs | 8 ++++---- crates/common/src/class_definition.rs | 16 ++++++++++++++++ .../src/p2p_network/sync/sync_handlers.rs | 12 ++++++++---- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/crates/class-hash/src/lib.rs b/crates/class-hash/src/lib.rs index db8380641d..884057c7ef 100644 --- a/crates/class-hash/src/lib.rs +++ b/crates/class-hash/src/lib.rs @@ -109,8 +109,8 @@ 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. - SerializedClassDefinition::Sierra(SerializedSierraDefinition::from_vec( - serialized_definition.into_vec(), + SerializedClassDefinition::Sierra(SerializedSierraDefinition::from( + serialized_definition.into_inner(), )), ) }), @@ -122,8 +122,8 @@ 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. - SerializedClassDefinition::Cairo(SerializedCairoDefinition::from_vec( - serialized_definition.into_vec(), + SerializedClassDefinition::Cairo(SerializedCairoDefinition::from( + serialized_definition.into_inner(), )), ) }), diff --git a/crates/common/src/class_definition.rs b/crates/common/src/class_definition.rs index 6d9b6400df..653a95eb7b 100644 --- a/crates/common/src/class_definition.rs +++ b/crates/common/src/class_definition.rs @@ -232,6 +232,12 @@ impl SerializedSierraDefinition { } } +impl From for SerializedSierraDefinition { + fn from(bytes: Bytes) -> Self { + Self(bytes) + } +} + impl SerializedCasmDefinition { pub fn from_vec(bytes: Vec) -> Self { Self(Bytes::from_owner(bytes)) @@ -268,6 +274,12 @@ impl SerializedCairoDefinition { } } +impl From for SerializedCairoDefinition { + fn from(bytes: Bytes) -> Self { + Self(bytes) + } +} + impl SerializedOpaqueClassDefinition { pub fn from_vec(bytes: Vec) -> Self { Self(Bytes::from_owner(bytes)) @@ -284,6 +296,10 @@ impl SerializedOpaqueClassDefinition { pub fn as_slice(&self) -> &[u8] { &self.0 } + + pub fn into_inner(self) -> Bytes { + self.0 + } } /// We can use `From` because this is always safe. diff --git a/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs b/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs index 86373823c8..fdee9cbb85 100644 --- a/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs +++ b/crates/pathfinder/src/p2p_network/sync/sync_handlers.rs @@ -166,12 +166,16 @@ fn get_classes_for_block( .is_sierra(class_hash)? .expect("Class definition exists in storage") { - SerializedClassDefinition::Sierra(SerializedSierraDefinition::from_vec( - definition.into_vec(), + // Assumption: it is safe to reinterpret the serialized definition as a Sierra + // definition since there is an accompanying casm definition for the class hash. + SerializedClassDefinition::Sierra(SerializedSierraDefinition::from( + definition.into_inner(), )) } else { - SerializedClassDefinition::Cairo(SerializedCairoDefinition::from_vec( - definition.into_vec(), + // Assumption: it is safe to reinterpret the serialized definition as a Cairo + // definition since there is no accompanying casm definition for the class hash. + SerializedClassDefinition::Cairo(SerializedCairoDefinition::from( + definition.into_inner(), )) };