WIP: change hash pros to get pros
This commit is contained in:
parent
c16b747a73
commit
77511e3a76
4 changed files with 50 additions and 27 deletions
|
@ -292,21 +292,23 @@ impl SparseMerkleTree<SMT_DEPTH> for Smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_prospective_leaf(&self, key: &RpoDigest, value: &Word) -> RpoDigest {
|
fn get_prospective_leaf(
|
||||||
// Future work could avoid cloning the leaf by mirroring some of the insertion logic and
|
&self,
|
||||||
// hashing without an intermediate leaf, but cloning is only expensive for multi-leaves,
|
mut existing_leaf: SmtLeaf,
|
||||||
// which should be really rare.
|
key: &RpoDigest,
|
||||||
let leaf_index: LeafIndex<SMT_DEPTH> = Self::key_to_leaf_index(key);
|
value: &Word,
|
||||||
match self.leaves.get(&leaf_index.value()) {
|
) -> SmtLeaf {
|
||||||
None => SmtLeaf::new_single(*key, *value).hash(),
|
debug_assert_eq!(existing_leaf.index(), Self::key_to_leaf_index(key));
|
||||||
Some(existing_leaf) => {
|
|
||||||
let mut new_leaf = existing_leaf.clone();
|
match existing_leaf {
|
||||||
|
SmtLeaf::Empty(_) => SmtLeaf::new_single(*key, *value),
|
||||||
|
_ => {
|
||||||
if *value != EMPTY_WORD {
|
if *value != EMPTY_WORD {
|
||||||
new_leaf.insert(*key, *value);
|
existing_leaf.insert(*key, *value);
|
||||||
} else {
|
} else {
|
||||||
new_leaf.remove(*key);
|
existing_leaf.remove(*key);
|
||||||
}
|
}
|
||||||
new_leaf.hash()
|
existing_leaf
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,7 @@ fn test_checked_insertion() {
|
||||||
|
|
||||||
// insert key-value 1
|
// insert key-value 1
|
||||||
let root_1 = {
|
let root_1 = {
|
||||||
let prospective = smt.hash_prospective_leaf(&key_1, &value_1);
|
let prospective = smt.get_prospective_leaf(smt.get_leaf(&key_1), &key_1, &value_1).hash();
|
||||||
let old_value_1 = smt.insert(key_1, value_1);
|
let old_value_1 = smt.insert(key_1, value_1);
|
||||||
assert_eq!(old_value_1, EMPTY_WORD);
|
assert_eq!(old_value_1, EMPTY_WORD);
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ fn test_checked_insertion() {
|
||||||
|
|
||||||
// insert key-value 2
|
// insert key-value 2
|
||||||
let root_2 = {
|
let root_2 = {
|
||||||
let prospective = smt.hash_prospective_leaf(&key_2, &value_2);
|
let prospective = smt.get_prospective_leaf(smt.get_leaf(&key_2), &key_2, &value_2).hash();
|
||||||
let old_value_2 = smt.insert(key_2, value_2);
|
let old_value_2 = smt.insert(key_2, value_2);
|
||||||
assert_eq!(old_value_2, EMPTY_WORD);
|
assert_eq!(old_value_2, EMPTY_WORD);
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ fn test_checked_insertion() {
|
||||||
|
|
||||||
// insert key-value 3
|
// insert key-value 3
|
||||||
let root_3 = {
|
let root_3 = {
|
||||||
let prospective = smt.hash_prospective_leaf(&key_3, &value_3);
|
let prospective = smt.get_prospective_leaf(smt.get_leaf(&key_3), &key_3, &value_3).hash();
|
||||||
let old_value_3 = smt.insert(key_3, value_3);
|
let old_value_3 = smt.insert(key_3, value_3);
|
||||||
assert_eq!(old_value_3, EMPTY_WORD);
|
assert_eq!(old_value_3, EMPTY_WORD);
|
||||||
|
|
||||||
|
@ -374,7 +374,10 @@ fn test_checked_insertion() {
|
||||||
let old_hash = smt.get_leaf(&key_3).hash();
|
let old_hash = smt.get_leaf(&key_3).hash();
|
||||||
let old_value_3 = smt.insert_ensure_root(key_3, EMPTY_WORD, root_2).unwrap();
|
let old_value_3 = smt.insert_ensure_root(key_3, EMPTY_WORD, root_2).unwrap();
|
||||||
assert_eq!(old_value_3, value_3);
|
assert_eq!(old_value_3, value_3);
|
||||||
assert_eq!(old_hash, smt.hash_prospective_leaf(&key_3, &old_value_3));
|
assert_eq!(
|
||||||
|
old_hash,
|
||||||
|
smt.get_prospective_leaf(smt.get_leaf(&key_3), &key_3, &old_value_3).hash()
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
smt.get_leaf(&key_3),
|
smt.get_leaf(&key_3),
|
||||||
|
@ -389,7 +392,10 @@ fn test_checked_insertion() {
|
||||||
let old_hash = smt.get_leaf(&key_2).hash();
|
let old_hash = smt.get_leaf(&key_2).hash();
|
||||||
let old_value_2 = smt.insert_ensure_root(key_2, EMPTY_WORD, root_1).unwrap();
|
let old_value_2 = smt.insert_ensure_root(key_2, EMPTY_WORD, root_1).unwrap();
|
||||||
assert_eq!(old_value_2, value_2);
|
assert_eq!(old_value_2, value_2);
|
||||||
assert_eq!(old_hash, smt.hash_prospective_leaf(&key_2, &old_value_2));
|
assert_eq!(
|
||||||
|
old_hash,
|
||||||
|
smt.get_prospective_leaf(smt.get_leaf(&key_2), &key_2, &old_value_2).hash()
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(smt.get_leaf(&key_2), SmtLeaf::Single((key_1, value_1)));
|
assert_eq!(smt.get_leaf(&key_2), SmtLeaf::Single((key_1, value_1)));
|
||||||
|
|
||||||
|
@ -401,7 +407,10 @@ fn test_checked_insertion() {
|
||||||
let old_hash = smt.get_leaf(&key_1).hash();
|
let old_hash = smt.get_leaf(&key_1).hash();
|
||||||
let old_value_1 = smt.insert_ensure_root(key_1, EMPTY_WORD, root_empty).unwrap();
|
let old_value_1 = smt.insert_ensure_root(key_1, EMPTY_WORD, root_empty).unwrap();
|
||||||
assert_eq!(old_value_1, value_1);
|
assert_eq!(old_value_1, value_1);
|
||||||
assert_eq!(old_hash, smt.hash_prospective_leaf(&key_1, &old_value_1));
|
assert_eq!(
|
||||||
|
old_hash,
|
||||||
|
smt.get_prospective_leaf(smt.get_leaf(&key_1), &key_1, &old_value_1).hash()
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(smt.get_leaf(&key_1), SmtLeaf::new_empty(key_1.into()));
|
assert_eq!(smt.get_leaf(&key_1), SmtLeaf::new_empty(key_1.into()));
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,8 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8> {
|
||||||
NodeIndex::from(leaf_index)
|
NodeIndex::from(leaf_index)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut new_child_hash = self.hash_prospective_leaf(&key, &value);
|
let mut new_child_hash =
|
||||||
|
Self::hash_leaf(&self.get_prospective_leaf(self.get_leaf(&key), &key, &value));
|
||||||
for node_depth in (0..node_index.depth()).rev() {
|
for node_depth in (0..node_index.depth()).rev() {
|
||||||
let is_right = node_index.is_value_odd();
|
let is_right = node_index.is_value_odd();
|
||||||
node_index.move_up();
|
node_index.move_up();
|
||||||
|
@ -260,13 +261,19 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8> {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn is_leaf_empty(leaf: &Self::Leaf) -> bool;
|
fn is_leaf_empty(leaf: &Self::Leaf) -> bool;
|
||||||
|
|
||||||
/// Returns the hash of a leaf if the leaf WERE inserted into the tree,
|
/// Returns what `existing_leaf` would look like if `key` and `value` WERE inserted into the
|
||||||
/// without performing any insertion or other mutation.
|
/// tree, without mutating the tree itself.
|
||||||
///
|
///
|
||||||
/// Note: calling this function after actually performing an insert with the same arguments
|
/// `existing_leaf` must have the same index as the key, or the result will be meaningless. To
|
||||||
/// will *not* return the same result, as inserting multiple times with the same key mutates
|
/// get a prospective leaf based on the current state of the tree, use `self.get_leaf(key)` as
|
||||||
/// the leaf each time.
|
/// the argument for `existing_leaf`. The return value from this function can be chained back
|
||||||
fn hash_prospective_leaf(&self, key: &Self::Key, value: &Self::Value) -> RpoDigest;
|
/// into this function as the first argument to continue making prospective changes.
|
||||||
|
fn get_prospective_leaf(
|
||||||
|
&self,
|
||||||
|
existing_leaf: Self::Leaf,
|
||||||
|
key: &Self::Key,
|
||||||
|
value: &Self::Value,
|
||||||
|
) -> Self::Leaf;
|
||||||
|
|
||||||
/// Maps a key to a leaf index
|
/// Maps a key to a leaf index
|
||||||
fn key_to_leaf_index(key: &Self::Key) -> LeafIndex<DEPTH>;
|
fn key_to_leaf_index(key: &Self::Key) -> LeafIndex<DEPTH>;
|
||||||
|
|
|
@ -328,8 +328,13 @@ impl<const DEPTH: u8> SparseMerkleTree<DEPTH> for SimpleSmt<DEPTH> {
|
||||||
*leaf == Self::EMPTY_VALUE
|
*leaf == Self::EMPTY_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_prospective_leaf(&self, _key: &LeafIndex<DEPTH>, value: &Word) -> RpoDigest {
|
fn get_prospective_leaf(
|
||||||
Self::hash_leaf(value)
|
&self,
|
||||||
|
_existing_leaf: Word,
|
||||||
|
_key: &LeafIndex<DEPTH>,
|
||||||
|
value: &Word,
|
||||||
|
) -> Word {
|
||||||
|
*value
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_to_leaf_index(key: &LeafIndex<DEPTH>) -> LeafIndex<DEPTH> {
|
fn key_to_leaf_index(key: &LeafIndex<DEPTH>) -> LeafIndex<DEPTH> {
|
||||||
|
|
Loading…
Add table
Reference in a new issue