Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions durable-storage/src/commit_operation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use crate::merkle_layer::hash;
use crate::merkle_layer::node::MavlNode;
use octez_riscv_data::hash::DIGEST_SIZE;
use std::collections::HashMap;
use std::sync::Arc;

#[derive(Clone, Debug)]
enum CommitOperationType {
Insert,
Remove,
}

#[derive(Clone, Debug)]
struct CommitOperation {
operation_type: CommitOperationType,
data: Option<Vec<u8>>,
}

impl CommitOperation {
fn insert_operation(data: Vec<u8>) -> Self {
Self {
operation_type: CommitOperationType::Insert,
data: Some(data),
}
}

fn remove_operation() -> Self {
Self {
operation_type: CommitOperationType::Remove,
data: None,
}
}
}

#[derive(Clone, Debug, Default)]
pub(crate) struct CommitOperationCollection {
collection: HashMap<[u8; DIGEST_SIZE], CommitOperation>,
}

impl CommitOperationCollection {
pub(crate) fn add_new_node_to_commit(&mut self, node: &Arc<MavlNode>) {
let node_hash: [u8; 32] = *hash(node).as_bytes();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is a bit too expensive to calculate here. We should store the key rather.

let serialized_node = node.encode_to_vec();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably not needed at this stage.

self.collection.insert(
node_hash,
CommitOperation::insert_operation(serialized_node),
);
}

pub(crate) fn remove_node_from_commit(&mut self, node: &Arc<MavlNode>) {
let node_hash: [u8; 32] = *hash(node).as_bytes();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also should not hash here, but just store the key. But we should also take ownership of the data of the node, so here we probably want to serialise the data or just own the node by owning its Arc.

self.collection
.insert(node_hash, CommitOperation::remove_operation());
}
}
1 change: 1 addition & 0 deletions durable-storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
//! - **Persistence layer**: Responsible for actually persisting the basic get, set, delete
//! operations on disk.

mod commit_operation;
#[cfg_attr(not(test), expect(dead_code, reason = "Incomplete"))]
mod merkle_layer;
mod merkle_worker;
Expand Down
23 changes: 21 additions & 2 deletions durable-storage/src/merkle_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ use std::sync::Arc;

use bytes::Bytes;

mod node;
pub(crate) mod node;
use node::MavlNode;
mod node_operations;
mod tree;

use bincode::Decode;
use bincode::Encode;
use tree::Avl;

use crate::commit_operation::CommitOperationCollection;
use crate::persistence_layer::PersistenceLayer;
use octez_riscv_data::serialisation::serialise_into;

/// An identifier generated for a given commit.
#[derive(Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -54,6 +58,7 @@ pub struct MerkleLayer {
tree: Avl,
#[expect(dead_code, reason = "To be used in RV-825")]
persistence: Arc<PersistenceLayer>,
commit_collection: CommitOperationCollection,
}

/// A layer for transforming data into a Merkelised representation before commitment to the [PersistenceLayer].
Expand All @@ -63,6 +68,7 @@ impl MerkleLayer {
MerkleLayer {
tree: Avl::default(),
persistence,
commit_collection: Default::default(),
}
}

Expand Down Expand Up @@ -115,10 +121,23 @@ impl MerkleLayer {

/// Sets the data associated with a given [Key].
pub fn set(&mut self, key: &Key, data: Bytes) {
self.tree.set(key, data)
self.tree.set(key, data, &mut self.commit_collection)
}
}

/// Returns the hash of this node, including recursively hashing any child nodes.
///
/// If the hash has been cached, the memo is returned. Otherwise, the hash is calculated and
/// cached.
pub(crate) fn hash(node: &Arc<MavlNode>) -> &blake3::Hash {
node.hash.get_or_init(|| {
let mut hasher = blake3::Hasher::new();
serialise_into(node.to_encode(), &mut hasher)
.expect("None of the `EncodeError`s can be triggered by this encoding");
hasher.finalize()
})
}

#[cfg(test)]
mod tests {
use std::path::Path;
Expand Down
Loading
Loading