Skip to content

Commit

Permalink
refactor: implement serializable trait for filled node from exists me…
Browse files Browse the repository at this point in the history
…thods
  • Loading branch information
AvivYossef-starkware committed Apr 24, 2024
1 parent 15f5469 commit 50ed640
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 34 deletions.
5 changes: 2 additions & 3 deletions crates/committer/src/patricia_merkle_tree/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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."
Expand Down
41 changes: 23 additions & 18 deletions crates/committer/src/patricia_merkle_tree/filled_tree/node_serde.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<StorageValue, SerializationError>;
type FilledNodeDeserializationResult = Result<FilledNode<LeafData>, SerializationError>;

impl FilledNode<LeafData> {
pub(crate) fn suffix(&self) -> [u8; SERIALIZE_HASH_BYTES] {
self.hash.0.as_bytes()
}
}

impl Serializable for FilledNode<LeafData> {
/// 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<StorageValue> {
fn serialize(&self) -> FilledNodeSerializationResult {
match &self.data {
NodeData::Binary(BinaryData {
left_hash,
Expand Down Expand Up @@ -60,16 +75,9 @@ impl FilledNode<LeafData> {
}
}

/// 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 {
Expand All @@ -90,10 +98,7 @@ impl FilledNode<LeafData> {

/// 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<Self> {
fn deserialize(key: &StorageKey, value: &StorageValue) -> FilledNodeDeserializationResult {
if value.0.len() == BINARY_BYTES {
Ok(Self {
hash: HashOutput(Felt::from_bytes_be_slice(&key.0)),
Expand Down
2 changes: 0 additions & 2 deletions crates/committer/src/patricia_merkle_tree/filled_tree/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,3 @@ impl<L: LeafDataTrait> FilledTree<L> for FilledTreeImpl<L> {
}
}
}

pub(crate) type FilledTreeResult<T> = Result<T, FilledTreeError>;
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
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.
#[derive(Serialize, Deserialize)]
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.
/// The serialization is done as follows:
/// - 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<StorageValue, FilledTreeError> {
pub(crate) fn serialize(&self) -> Result<StorageValue, SerializationError> {
match &self {
LeafData::StorageValue(value) => Ok(StorageValue(value.as_bytes().to_vec())),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ 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;
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;
Expand Down
12 changes: 8 additions & 4 deletions crates/committer/src/storage/errors.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
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 {
#[error("The key {0:?} does not exist in storage.")]
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),
}
2 changes: 1 addition & 1 deletion crates/committer/src/storage/serde_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub(crate) trait Serializable {
/// Serializes the given value.
fn serialize(&self) -> Result<StorageValue, SerializationError>;
/// Deserializes the given value.
fn deserialize(key: StorageKey, value: StorageValue) -> Result<Self, SerializationError>
fn deserialize(key: &StorageKey, value: &StorageValue) -> Result<Self, SerializationError>
where
Self: Sized;
/// Returns the key used to store self in storage.
Expand Down

0 comments on commit 50ed640

Please sign in to comment.