From 56e97ae7a18bead5e18279fc06cf13f1c1381f41 Mon Sep 17 00:00:00 2001 From: Milosz Muszynski Date: Sun, 13 Oct 2024 02:09:56 +0200 Subject: [PATCH] piecurst: recursive finding elements of base commits --- piecrust/src/store.rs | 89 +++++++---------------------------- piecrust/src/store/session.rs | 37 ++++++++++++++- 2 files changed, 52 insertions(+), 74 deletions(-) diff --git a/piecrust/src/store.rs b/piecrust/src/store.rs index 4a5a99cd..cee3a81d 100644 --- a/piecrust/src/store.rs +++ b/piecrust/src/store.rs @@ -41,7 +41,6 @@ pub use tree::PageOpening; const BYTECODE_DIR: &str = "bytecode"; const MEMORY_DIR: &str = "memory"; const LEAF_DIR: &str = "leaf"; -// const INDEX_FILE: &str = "index"; const MERKLE_FILE: &str = "merkle"; const BASE_FILE: &str = "base"; const ELEMENT_FILE: &str = "element"; @@ -205,12 +204,6 @@ fn read_all_commits>( let root_dir = root_dir.join(MAIN_DIR); fs::create_dir_all(root_dir.clone())?; - // if root_dir.join(INDEX_FILE).is_file() { - // let commit = read_commit(engine, root_dir.clone())?; - // let root = *commit.root(); - // commits.insert(root, commit); - // } - for entry in fs::read_dir(root_dir)? { let entry = entry?; if entry.path().is_dir() { @@ -254,16 +247,6 @@ fn page_path_main, S: AsRef>( Ok(dir.join(format!("{page_index}"))) } -// fn index_path_main, S: AsRef>( -// main_dir: P, -// commit_id: S, -// ) -> io::Result { -// let commit_id = commit_id.as_ref(); -// let dir = main_dir.as_ref().join(commit_id); -// fs::create_dir_all(&dir)?; -// Ok(dir.join(INDEX_FILE)) -// } - fn merkle_path_main, S: AsRef>( main_dir: P, commit_id: S, @@ -327,8 +310,12 @@ fn commit_from_dir>( let contracts_merkle_path = dir.join(MERKLE_FILE); let leaf_dir = main_dir.join(LEAF_DIR); - let (index, contracts_merkle) = - index_merkle_from_path(contracts_merkle_path, leaf_dir, &maybe_hash)?; + let (index, contracts_merkle) = index_merkle_from_path( + main_dir, + contracts_merkle_path, + leaf_dir, + &maybe_hash, + )?; let bytecode_dir = main_dir.join(BYTECODE_DIR); let memory_dir = main_dir.join(MEMORY_DIR); @@ -390,54 +377,29 @@ fn commit_from_dir>( }) } -fn index_merkle_from_path, P2: AsRef>( - merkle_path: P1, - leaf_dir: P2, +fn index_merkle_from_path, P2: AsRef, P3: AsRef>( + main_path: P1, + merkle_path: P2, + leaf_dir: P3, maybe_commit_id: &Option, ) -> io::Result<(NewContractIndex, ContractsMerkle)> { - // let path = path.as_ref(); let merkle_path = merkle_path.as_ref(); let leaf_dir = leaf_dir.as_ref(); - // tracing::trace!("reading index file started"); - // let index_bytes = fs::read(path)?; - // tracing::trace!("reading index file finished"); - // tracing::trace!("deserializing index file started"); let mut index: NewContractIndex = NewContractIndex::new(); - // rkyv::from_bytes(&index_bytes).map_err(|err| { - // tracing::trace!("deserializing index file failed {}", err); - // io::Error::new( - // io::ErrorKind::InvalidData, - // format!("Invalid index file \"{path:?}\": {err}"), - // ) - // })?; - // tracing::trace!("deserializing index file finished"); - // compare index with disk representation for entry in fs::read_dir(leaf_dir)? { let entry = entry?; if entry.path().is_dir() { let contract_id_hex = entry.file_name().to_string_lossy().to_string(); let contract_id = contract_id_from_hex(contract_id_hex.clone()); - let element_path = match maybe_commit_id { - Some(commit_id) => { - let contract_leaf_dir = leaf_dir.join(contract_id_hex); - let leaf_file_path = contract_leaf_dir - .join(hex::encode(commit_id.as_bytes())) - .join(ELEMENT_FILE); - if leaf_file_path.is_file() { - leaf_file_path - } else { - contract_leaf_dir.join(ELEMENT_FILE) - } - } - None => leaf_dir.join(contract_id_hex).join(ELEMENT_FILE), - }; - println!( - "element_path={:?} is_file={}", - element_path, - element_path.is_file() - ); + let contract_leaf_path = leaf_dir.join(contract_id_hex); + let element_path = ContractSession::find_element( + *maybe_commit_id, + contract_leaf_path.clone(), + main_path.as_ref(), + ) + .unwrap_or(contract_leaf_path.join(ELEMENT_FILE)); let element_bytes = fs::read(element_path.clone())?; let element: ContractIndexElement = rkyv::from_bytes(&element_bytes).map_err(|err| { @@ -896,23 +858,9 @@ fn write_commit_inner, S: AsRef>( } } - // let index_main_path = - // index_path_main(directories.main_dir.clone(), commit_id.as_ref())?; let merkle_main_path = merkle_path_main(directories.main_dir.clone(), commit_id.as_ref())?; - // tracing::trace!("serializing index started"); - // let index_bytes = - // rkyv::to_bytes::<_, 128>(&commit.index).map_err(|err| { - // io::Error::new( - // io::ErrorKind::InvalidData, - // format!("Failed serializing index file: {err}"), - // ) - // })?; - // tracing::trace!("serializing index finished"); - // tracing::trace!("writing index file started"); - // fs::write(index_main_path.clone(), index_bytes)?; - // tracing::trace!("writing index file finished"); for (contract_id, element) in commit.index.iter() { if commit_contracts.contains_key(contract_id) { // todo: write element to disk at @@ -1033,9 +981,6 @@ fn finalize_commit>( } fs::remove_dir(src_leaf_path.clone())?; } - // let index_path = commit_path.join(INDEX_FILE); - // let dst_index_path = main_dir.join(INDEX_FILE); - // fs::rename(index_path.clone(), dst_index_path.clone())?; let merkle_path = commit_path.join(MERKLE_FILE); let dst_merkle_path = main_dir.join(MERKLE_FILE); diff --git a/piecrust/src/store/session.rs b/piecrust/src/store/session.rs index 1b07f613..21520e5f 100644 --- a/piecrust/src/store/session.rs +++ b/piecrust/src/store/session.rs @@ -18,8 +18,8 @@ use crate::contract::ContractMetadata; use crate::store::tree::{Hash, PageOpening}; use crate::store::{ base_from_path, Bytecode, Call, Commit, Memory, Metadata, Module, - BASE_FILE, BYTECODE_DIR, MAIN_DIR, MEMORY_DIR, METADATA_EXTENSION, - OBJECTCODE_EXTENSION, PAGE_SIZE, + BASE_FILE, BYTECODE_DIR, ELEMENT_FILE, MAIN_DIR, MEMORY_DIR, + METADATA_EXTENSION, OBJECTCODE_EXTENSION, PAGE_SIZE, }; use crate::Error; @@ -196,6 +196,39 @@ impl ContractSession { } } + /// Returns path to a file representing a given commit and element. + /// + /// Requires a contract's leaf path and a main state path. + /// Progresses recursively via bases of commits. + pub fn find_element( + commit: Option, + leaf_path: impl AsRef, + main_path: impl AsRef, + ) -> Option { + match commit { + None => None, + Some(hash) => { + let hash_hex = hex::encode(hash.as_bytes()); + let path = leaf_path + .as_ref() + .join(hash_hex.clone()) + .join(ELEMENT_FILE); + if path.is_file() { + Some(path) + } else { + let base_info_path = + main_path.as_ref().join(hash_hex).join(BASE_FILE); + let index = base_from_path(base_info_path).ok()?; + Self::find_element( + index.maybe_base, + leaf_path.as_ref(), + main_path.as_ref(), + ) + } + } + } + } + /// Return the bytecode and memory belonging to the given `contract`, if it /// exists. ///