Skip to content

Commit

Permalink
incipient position hash
Browse files Browse the repository at this point in the history
  • Loading branch information
miloszm committed Oct 13, 2024
1 parent 42d56fb commit 7eb09b9
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 19 deletions.
93 changes: 74 additions & 19 deletions piecrust/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use tree::{Hash, NewContractIndex};

use crate::store::tree::{
position_from_contract, BaseInfo, ContractIndexElement, ContractsMerkle,
PageTree,
PageTree, PosHash,
};
pub use bytecode::Bytecode;
pub use memory::{Memory, PAGE_SIZE};
Expand All @@ -42,6 +42,7 @@ const BYTECODE_DIR: &str = "bytecode";
const MEMORY_DIR: &str = "memory";
const LEAF_DIR: &str = "leaf";
const MERKLE_FILE: &str = "merkle";
const POS_HASH_FILE: &str = "pos_hash";
const BASE_FILE: &str = "base";
const ELEMENT_FILE: &str = "element";
const OBJECTCODE_EXTENSION: &str = "a";
Expand Down Expand Up @@ -251,6 +252,16 @@ fn merkle_path_main<P: AsRef<Path>, S: AsRef<str>>(
Ok(dir.join(MERKLE_FILE))
}

fn pos_hash_path_main<P: AsRef<Path>, S: AsRef<str>>(
main_dir: P,
commit_id: S,
) -> io::Result<PathBuf> {
let commit_id = commit_id.as_ref();
let dir = main_dir.as_ref().join(commit_id);
fs::create_dir_all(&dir)?;
Ok(dir.join(POS_HASH_FILE))
}

fn base_path_main<P: AsRef<Path>, S: AsRef<str>>(
main_dir: P,
commit_id: S,
Expand Down Expand Up @@ -303,11 +314,13 @@ fn commit_from_dir<P: AsRef<Path>>(
let maybe_hash = commit_id.as_ref().map(commit_id_to_hash);

let contracts_merkle_path = dir.join(MERKLE_FILE);
let pos_hash_path = dir.join(POS_HASH_FILE);
let leaf_dir = main_dir.join(LEAF_DIR);
let (index, contracts_merkle) = index_merkle_from_path(
let (index, contracts_merkle, pos_hash) = index_merkle_pos_hash_from_path(
main_dir,
contracts_merkle_path,
leaf_dir,
pos_hash_path,
&maybe_hash,
)?;

Expand Down Expand Up @@ -368,16 +381,24 @@ fn commit_from_dir<P: AsRef<Path>>(
index,
contracts_merkle,
maybe_hash,
pos_hash,
})
}

fn index_merkle_from_path<P1: AsRef<Path>, P2: AsRef<Path>, P3: AsRef<Path>>(
fn index_merkle_pos_hash_from_path<
P1: AsRef<Path>,
P2: AsRef<Path>,
P3: AsRef<Path>,
P4: AsRef<Path>,
>(
main_path: P1,
merkle_path: P2,
leaf_dir: P3,
pos_hash_path: P4,
maybe_commit_id: &Option<Hash>,
) -> io::Result<(NewContractIndex, ContractsMerkle)> {
) -> io::Result<(NewContractIndex, ContractsMerkle, PosHash)> {
let merkle_path = merkle_path.as_ref();
let pos_hash_path = pos_hash_path.as_ref();
let leaf_dir = leaf_dir.as_ref();

let mut index: NewContractIndex = NewContractIndex::new();
Expand All @@ -396,21 +417,19 @@ fn index_merkle_from_path<P1: AsRef<Path>, P2: AsRef<Path>, P3: AsRef<Path>>(
.unwrap_or(contract_leaf_path.join(ELEMENT_FILE));
if element_path.is_file() {
let element_bytes = fs::read(element_path.clone())?;
let element: ContractIndexElement = rkyv::from_bytes(
&element_bytes,
)
.map_err(|err| {
tracing::trace!(
"deserializing element file failed {}",
err
);
io::Error::new(
io::ErrorKind::InvalidData,
format!(
let element: ContractIndexElement =
rkyv::from_bytes(&element_bytes).map_err(|err| {
tracing::trace!(
"deserializing element file failed {}",
err
);
io::Error::new(
io::ErrorKind::InvalidData,
format!(
"Invalid element file \"{element_path:?}\": {err}"
),
)
})?;
)
})?;
index.insert_contract_index(&contract_id, element)
}
}
Expand All @@ -429,7 +448,22 @@ fn index_merkle_from_path<P1: AsRef<Path>, P2: AsRef<Path>, P3: AsRef<Path>>(
})?;
tracing::trace!("deserializing contracts merkle file finished");

Ok((index, merkle))
let pos_hash = if pos_hash_path.is_file() {
let pos_hash_bytes = fs::read(pos_hash_path)?;
rkyv::from_bytes(&pos_hash_bytes).map_err(|err| {
tracing::trace!("deserializing position hash file failed {}", err);
io::Error::new(
io::ErrorKind::InvalidData,
format!(
"Invalid position hash file \"{pos_hash_path:?}\": {err}"
),
)
})?
} else {
PosHash::new()
};

Ok((index, merkle, pos_hash))
}

fn base_from_path<P: AsRef<Path>>(path: P) -> io::Result<BaseInfo> {
Expand All @@ -451,6 +485,7 @@ pub(crate) struct Commit {
index: NewContractIndex,
contracts_merkle: ContractsMerkle,
maybe_hash: Option<Hash>,
pos_hash: PosHash,
}

impl Commit {
Expand All @@ -459,6 +494,7 @@ impl Commit {
index: NewContractIndex::new(),
contracts_merkle: ContractsMerkle::default(),
maybe_hash: None,
pos_hash: PosHash::new(),
}
}

Expand Down Expand Up @@ -733,10 +769,14 @@ fn write_commit<P: AsRef<Path>>(
base.as_ref().map_or(ContractsMerkle::default(), |base| {
base.contracts_merkle.clone()
});
let pos_hash = base
.as_ref()
.map_or(PosHash::new(), |base| base.pos_hash.clone());
let mut commit = Commit {
index,
contracts_merkle,
maybe_hash: base.as_ref().map_or(None, |base| base.maybe_hash),
pos_hash,
};

for (contract_id, contract_data) in &commit_contracts {
Expand Down Expand Up @@ -856,6 +896,8 @@ fn write_commit_inner<P: AsRef<Path>, S: AsRef<str>>(

let merkle_main_path =
merkle_path_main(directories.main_dir.clone(), commit_id.as_ref())?;
let pos_hash_main_path =
pos_hash_path_main(directories.main_dir.clone(), commit_id.as_ref())?;

for (contract_id, element) in commit.index.iter() {
if commit_contracts.contains_key(contract_id) {
Expand Down Expand Up @@ -883,7 +925,7 @@ fn write_commit_inner<P: AsRef<Path>, S: AsRef<str>>(
.map_err(|err| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("Failed serializing contracts merkle file file: {err}"),
format!("Failed serializing contracts merkle file: {err}"),
)
})?;
tracing::trace!("serializing contracts merkle file finished");
Expand All @@ -902,6 +944,15 @@ fn write_commit_inner<P: AsRef<Path>, S: AsRef<str>>(
})?;
fs::write(base_main_path.clone(), base_info_bytes)?;

let pos_hash_bytes =
rkyv::to_bytes::<_, 128>(&commit.pos_hash).map_err(|err| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("Failed serializing position hash file: {err}"),
)
})?;
fs::write(pos_hash_main_path.clone(), pos_hash_bytes)?;

Ok(())
}

Expand Down Expand Up @@ -982,6 +1033,10 @@ fn finalize_commit<P: AsRef<Path>>(
let dst_merkle_path = main_dir.join(MERKLE_FILE);
fs::rename(merkle_path.clone(), dst_merkle_path.clone())?;

let pos_hash_path = commit_path.join(POS_HASH_FILE);
let dst_pos_hash_path = main_dir.join(POS_HASH_FILE);
fs::rename(pos_hash_path.clone(), dst_pos_hash_path.clone())?;

fs::remove_file(base_info_path)?;
fs::remove_dir(commit_path.clone())?;

Expand Down
1 change: 1 addition & 0 deletions piecrust/src/store/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ impl ContractSession {
index: c.index.clone(),
contracts_merkle: c.contracts_merkle.clone(),
maybe_hash: c.maybe_hash,
pos_hash: c.pos_hash.clone(),
});

mem::swap(&mut self.contracts, &mut contracts);
Expand Down
14 changes: 14 additions & 0 deletions piecrust/src/store/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ impl PageTree {

pub type Tree = dusk_merkle::Tree<Hash, C_HEIGHT, C_ARITY>;

#[derive(Debug, Clone, Archive, Deserialize, Serialize)]
#[archive_attr(derive(CheckBytes))]
pub struct PosHash {
pos_hash: BTreeMap<u64, Hash>,
}

impl PosHash {
pub fn new() -> Self {
Self {
pos_hash: BTreeMap::new(),
}
}
}

#[derive(Debug, Clone, Archive, Deserialize, Serialize)]
#[archive_attr(derive(CheckBytes))]
pub struct NewContractIndex {
Expand Down

0 comments on commit 7eb09b9

Please sign in to comment.