From 50ed64084034e060b0a665d26de13d6de0d81085 Mon Sep 17 00:00:00 2001 From: AvivYossef-starkware Date: Sun, 21 Apr 2024 15:36:01 +0300 Subject: [PATCH] refactor: implement serializable trait for filled node from exists methods --- .../src/patricia_merkle_tree/errors.rs | 5 +-- .../filled_tree/node_serde.rs | 41 +++++++++++-------- .../patricia_merkle_tree/filled_tree/tree.rs | 2 - .../node_data/leaf_serde.rs | 10 ++--- .../original_skeleton_calc.rs | 2 +- crates/committer/src/storage/errors.rs | 12 ++++-- crates/committer/src/storage/serde_trait.rs | 2 +- 7 files changed, 40 insertions(+), 34 deletions(-) diff --git a/crates/committer/src/patricia_merkle_tree/errors.rs b/crates/committer/src/patricia_merkle_tree/errors.rs index 34ef57ec..586b3b5e 100644 --- a/crates/committer/src/patricia_merkle_tree/errors.rs +++ b/crates/committer/src/patricia_merkle_tree/errors.rs @@ -2,8 +2,7 @@ use thiserror::Error; use crate::patricia_merkle_tree::node_data::leaf::LeafDataTrait; use crate::patricia_merkle_tree::types::NodeIndex; -use crate::storage::errors::StorageError; -use crate::storage::storage_trait::StorageValue; +use crate::storage::errors::{SerializationError, StorageError}; use crate::patricia_merkle_tree::filled_tree::node::FilledNode; @@ -13,7 +12,7 @@ pub(crate) enum OriginalSkeletonTreeError { #[error( "Failed to deserialize the storage value: {0:?} while building the original skeleton tree." )] - Deserialization(StorageValue), + Deserialization(#[from] SerializationError), #[error( "Unable to read from storage the storage key: {0:?} while building the \ original skeleton tree." diff --git a/crates/committer/src/patricia_merkle_tree/filled_tree/node_serde.rs b/crates/committer/src/patricia_merkle_tree/filled_tree/node_serde.rs index 585f6ac1..59f8599a 100644 --- a/crates/committer/src/patricia_merkle_tree/filled_tree/node_serde.rs +++ b/crates/committer/src/patricia_merkle_tree/filled_tree/node_serde.rs @@ -1,13 +1,14 @@ use crate::hash::hash_trait::HashOutput; use crate::patricia_merkle_tree::filled_tree::node::FilledNode; -use crate::patricia_merkle_tree::filled_tree::tree::FilledTreeResult; use crate::patricia_merkle_tree::node_data::inner_node::{ BinaryData, EdgeData, EdgePath, EdgePathLength, NodeData, PathToBottom, }; use crate::patricia_merkle_tree::node_data::leaf::LeafData; -use crate::patricia_merkle_tree::original_skeleton_tree::tree::OriginalSkeletonTreeResult; +use crate::storage::errors::SerializationError; +use crate::storage::serde_trait::Serializable; use crate::storage::storage_trait::{create_db_key, StorageKey, StoragePrefix, StorageValue}; use crate::types::Felt; +use serde::{Deserialize, Serialize}; // Const describe the size of the serialized node. pub(crate) const SERIALIZE_HASH_BYTES: usize = 32; @@ -18,16 +19,30 @@ pub(crate) const EDGE_BYTES: usize = SERIALIZE_HASH_BYTES + EDGE_PATH_BYTES + ED #[allow(dead_code)] pub(crate) const STORAGE_LEAF_SIZE: usize = SERIALIZE_HASH_BYTES; -// TODO(Aviv, 17/4/2024): add CompiledClassLeaf size. -// TODO(Aviv, 17/4/2024): add StateTreeLeaf size. +/// Temporary struct to serialize the leaf CompiledClass. +/// Required to comply to existing storage layout. +#[derive(Serialize, Deserialize)] +pub(crate) struct LeafCompiledClassToSerialize { + pub(crate) compiled_class_hash: Felt, +} + +/// Alias for serialization and deserialization results of filled nodes. +type FilledNodeSerializationResult = Result; +type FilledNodeDeserializationResult = Result, SerializationError>; impl FilledNode { + pub(crate) fn suffix(&self) -> [u8; SERIALIZE_HASH_BYTES] { + self.hash.0.as_bytes() + } +} + +impl Serializable for FilledNode { /// This method serializes the filled node into a byte vector, where: /// - For binary nodes: Concatenates left and right hashes. /// - For edge nodes: Concatenates bottom hash, path, and path length. /// - For leaf nodes: use leaf.serialize() method. #[allow(dead_code)] - pub(crate) fn serialize(&self) -> FilledTreeResult { + fn serialize(&self) -> FilledNodeSerializationResult { match &self.data { NodeData::Binary(BinaryData { left_hash, @@ -60,16 +75,9 @@ impl FilledNode { } } - /// Returns the suffix of the filled node, represented by its hash as a byte array. - #[allow(dead_code)] - pub(crate) fn suffix(&self) -> [u8; SERIALIZE_HASH_BYTES] { - self.hash.0.as_bytes() - } - - // TODO(Amos, 1/5/2024): move leaf logic to leaf_serde. - /// Returns the db key of the filled node. + /// Returns the db key of the filled node - [prefix + b":" + suffix]. #[allow(dead_code)] - pub(crate) fn db_key(&self) -> StorageKey { + fn db_key(&self) -> StorageKey { let suffix = self.suffix(); match &self.data { @@ -90,10 +98,7 @@ impl FilledNode { /// Deserializes non-leaf nodes; if a serialized leaf node is given, the hash /// is used but the data is ignored. - pub(crate) fn deserialize( - key: &StorageKey, - value: &StorageValue, - ) -> OriginalSkeletonTreeResult { + fn deserialize(key: &StorageKey, value: &StorageValue) -> FilledNodeDeserializationResult { if value.0.len() == BINARY_BYTES { Ok(Self { hash: HashOutput(Felt::from_bytes_be_slice(&key.0)), diff --git a/crates/committer/src/patricia_merkle_tree/filled_tree/tree.rs b/crates/committer/src/patricia_merkle_tree/filled_tree/tree.rs index 0f212da0..3cec4031 100644 --- a/crates/committer/src/patricia_merkle_tree/filled_tree/tree.rs +++ b/crates/committer/src/patricia_merkle_tree/filled_tree/tree.rs @@ -50,5 +50,3 @@ impl FilledTree for FilledTreeImpl { } } } - -pub(crate) type FilledTreeResult = Result; diff --git a/crates/committer/src/patricia_merkle_tree/node_data/leaf_serde.rs b/crates/committer/src/patricia_merkle_tree/node_data/leaf_serde.rs index 9031792e..bc113491 100644 --- a/crates/committer/src/patricia_merkle_tree/node_data/leaf_serde.rs +++ b/crates/committer/src/patricia_merkle_tree/node_data/leaf_serde.rs @@ -1,6 +1,9 @@ use serde::{Deserialize, Serialize}; -use crate::patricia_merkle_tree::errors::FilledTreeError; +use crate::patricia_merkle_tree::node_data::leaf::LeafData; +use crate::storage::errors::SerializationError; +use crate::storage::storage_trait::StorageValue; +use crate::types::Felt; /// Temporary struct to serialize the leaf CompiledClass. /// Required to comply to existing storage layout. @@ -8,9 +11,6 @@ use crate::patricia_merkle_tree::errors::FilledTreeError; pub(crate) struct LeafCompiledClassToSerialize { pub(crate) compiled_class_hash: Felt, } -use crate::patricia_merkle_tree::node_data::leaf::LeafData; -use crate::storage::storage_trait::StorageValue; -use crate::types::Felt; impl LeafData { /// Serializes the leaf data into a byte vector. @@ -18,7 +18,7 @@ impl LeafData { /// - For storage values: serializes the value into a 32-byte vector. /// - For compiled class hashes or state tree tuples: creates a json string /// describing the leaf and cast it into a byte vector. - pub(crate) fn serialize(&self) -> Result { + pub(crate) fn serialize(&self) -> Result { match &self { LeafData::StorageValue(value) => Ok(StorageValue(value.as_bytes().to_vec())), diff --git a/crates/committer/src/patricia_merkle_tree/original_skeleton_tree/original_skeleton_calc.rs b/crates/committer/src/patricia_merkle_tree/original_skeleton_tree/original_skeleton_calc.rs index 8dc8a1ad..89291f15 100644 --- a/crates/committer/src/patricia_merkle_tree/original_skeleton_tree/original_skeleton_calc.rs +++ b/crates/committer/src/patricia_merkle_tree/original_skeleton_tree/original_skeleton_calc.rs @@ -13,6 +13,7 @@ use crate::patricia_merkle_tree::{ original_skeleton_tree::node::OriginalSkeletonNode, types::NodeIndex, }; use crate::storage::errors::StorageError; +use crate::storage::serde_trait::Serializable; use crate::storage::storage_trait::create_db_key; use crate::storage::storage_trait::Storage; use crate::storage::storage_trait::StorageKey; @@ -20,7 +21,6 @@ use crate::storage::storage_trait::StoragePrefix; use crate::types::Felt; use bisection::{bisect_left, bisect_right}; use std::collections::HashMap; - #[cfg(test)] #[path = "original_skeleton_calc_test.rs"] pub mod original_skeleton_calc_test; diff --git a/crates/committer/src/storage/errors.rs b/crates/committer/src/storage/errors.rs index 0f7fd765..13fb7ef7 100644 --- a/crates/committer/src/storage/errors.rs +++ b/crates/committer/src/storage/errors.rs @@ -1,7 +1,9 @@ use crate::storage::storage_trait::StorageKey; -use derive_more::Display; +use serde_json; use thiserror::Error; +use crate::storage::storage_trait::StorageValue; + #[derive(Debug, Error)] #[allow(dead_code)] pub(crate) enum StorageError { @@ -9,9 +11,11 @@ pub(crate) enum StorageError { MissingKey(StorageKey), } -#[derive(thiserror::Error, Debug, Display)] +#[derive(thiserror::Error, Debug)] #[allow(dead_code)] pub(crate) enum SerializationError { - DeserializeError, - SerializeError, + #[error("Failed to deserialize the storage value: {0:?}")] + DeserializeError(StorageValue), + #[error("Serialize error: {0}")] + SerializeError(#[from] serde_json::Error), } diff --git a/crates/committer/src/storage/serde_trait.rs b/crates/committer/src/storage/serde_trait.rs index d277bda6..e8c15c7c 100644 --- a/crates/committer/src/storage/serde_trait.rs +++ b/crates/committer/src/storage/serde_trait.rs @@ -5,7 +5,7 @@ pub(crate) trait Serializable { /// Serializes the given value. fn serialize(&self) -> Result; /// Deserializes the given value. - fn deserialize(key: StorageKey, value: StorageValue) -> Result + fn deserialize(key: &StorageKey, value: &StorageValue) -> Result where Self: Sized; /// Returns the key used to store self in storage.