From 411354fbec0edde913a0ad7467e94b428661cf3e Mon Sep 17 00:00:00 2001 From: Qyriad Date: Thu, 29 Aug 2024 13:01:41 -0600 Subject: [PATCH] cleaned up working state --- src/merkle/smt/full/mod.rs | 2 +- src/merkle/smt/full/tests.rs | 20 ++ src/merkle/smt/mod.rs | 625 +++++++---------------------------- 3 files changed, 147 insertions(+), 500 deletions(-) diff --git a/src/merkle/smt/full/mod.rs b/src/merkle/smt/full/mod.rs index 866aa19..f05474b 100644 --- a/src/merkle/smt/full/mod.rs +++ b/src/merkle/smt/full/mod.rs @@ -19,7 +19,7 @@ mod proof; pub use proof::SmtProof; use winter_utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; -mod rollback; +//mod rollback; #[cfg(test)] mod tests; diff --git a/src/merkle/smt/full/tests.rs b/src/merkle/smt/full/tests.rs index b692cf6..718b14d 100644 --- a/src/merkle/smt/full/tests.rs +++ b/src/merkle/smt/full/tests.rs @@ -442,6 +442,7 @@ fn test_checked_insertion() { let new_parent_1 = mutations.get_inner_node(parent_1_index).unwrap(); assert_eq!(leaf_1_parent, new_parent_1); let mut index = NodeIndex::from(Smt::key_to_leaf_index(&key_1)); + for depth in (0..smt.depth()).rev() { let is_right = index.is_value_odd(); index.move_up(); @@ -500,6 +501,25 @@ fn test_checked_insertion() { } assert_eq!(mutations.new_root, root_2); + + let mut smt = smt; + //smt.apply_muts(mutations); + mutations.apply(&mut smt); + let smt = smt; + assert_eq!(smt.root(), root_2); + + let mut mutations = smt.start_muts(); + smt.good_insert(&mut mutations, key_2, EMPTY_WORD); + assert_eq!(mutations.new_root, root_1); + drop(mutations); + + let mut mutations = smt.start_muts(); + smt.good_insert(&mut mutations, key_3, value_3); + assert_eq!(mutations.new_root, root_3); + + let mut smt = smt; + mutations.apply(&mut smt); + assert_eq!(smt.root(), root_3); } /// Tests that 2 key-value pairs stored in the same leaf have the same path diff --git a/src/merkle/smt/mod.rs b/src/merkle/smt/mod.rs index 11b1ba7..f7eb818 100644 --- a/src/merkle/smt/mod.rs +++ b/src/merkle/smt/mod.rs @@ -2,7 +2,6 @@ use alloc::{ collections::{btree_map::Entry, BTreeMap}, vec::Vec, }; -use tap::Pipe; use super::{EmptySubtreeRoots, InnerNodeInfo, MerkleError, MerklePath, NodeIndex}; use crate::{ @@ -154,15 +153,6 @@ pub(crate) trait SparseMerkleTree: Clone { return Ok(value); } - //let mut mutations = Mutations::new(); - //self.prospective_insert(&mut mutations, key.clone(), value.clone()); - //let Mutations { - // mut node_removals, - // mut node_additions, - // mut pair_insertions, - // new_root, - //} = mutations; - let mut control = self.clone(); control.insert(key.clone(), value.clone()); @@ -174,18 +164,6 @@ pub(crate) trait SparseMerkleTree: Clone { for depth in (0..index.depth()).rev() { index.move_up(); assert_eq!(depth, index.depth()); - - let control_node = control.get_inner_node(index); - let test_node = mutations.maybe_get_node(index).or_empty(); - //let test_node = match mutations.get_inner_node(index) { - // Some(node) => node, - // None => { - // let &child = EmptySubtreeRoots::entry(DEPTH, index.depth() + 1); - // InnerNode { left: child, right: child } - // }, - //}; - - assert_eq!(control_node, test_node, "nodes at {index:?} are different!"); } assert_eq!(control.root(), mutations.new_root); @@ -196,118 +174,12 @@ pub(crate) trait SparseMerkleTree: Clone { self.apply_muts(mutations); - // Actual mutations start here. - //self.apply_mutations(mutations); - - //for (key, value) in pair_insertions.drain(..) { - // self.insert_value(key, value); - //} - // - //for index in node_removals.drain(..) { - // self.remove_inner_node(index); - //} - // - //for (index, new_node) in node_additions.drain(..) { - // self.insert_inner_node(index, new_node); - //} - // - //self.set_root(new_root); - Ok(old_value) } - //fn prospective_insert( - // &self, - // mutations: &mut Mutations, - // key: Self::Key, - // value: Self::Value, - //) { - // let old_value = self.get_value(&key); - // // If the old value and new value are the same, there's nothing to update. - // if value == old_value { - // return; - // } - // - // let mut node_index = { - // let leaf_index: LeafIndex = Self::key_to_leaf_index(&key); - // NodeIndex::from(leaf_index) - // }; - // - // //let mut new_child_hash = self.hash_prospective_leaf(&key, &value); - // //let existing_leaf = match self.maybe_get_leaf(&key) { - // // Some(leaf) => Some(leaf), - // // None => mutations - // // .pair_insertions - // // .iter() - // // .find(|&pair| pair.0 == key) - // // .cloned() - // // .map(|pair| self.get_prospective_leaf(None, &pair.0, &pair.1)), - // //}; - // let maybe_prospective_leaf = mutations - // .pair_insertions - // .iter() - // .find(|&pair| pair.0 == key) - // .cloned() - // .map(|pair| self.get_prospective_leaf(None, &pair.0, &pair.1)); - // std::dbg!(&maybe_prospective_leaf); - // let existing_leaf = match maybe_prospective_leaf { - // Some(leaf) => Some(leaf), - // None => self.maybe_get_leaf(&key), - // }; - // let new_child = self.get_prospective_leaf(existing_leaf.as_ref(), &key, &value); - // let mut new_child_hash = Self::hash_leaf(&new_child); - // for node_depth in (0..node_index.depth()).rev() { - // let is_right = node_index.is_value_odd(); - // node_index.move_up(); - // - // //let old_node = self.get_inner_node(node_index); - // //let old_node = mutations.get_inner_node(node_index).unwrap_or_else(|| { - // // std::eprintln!("nothing in mutations, getting existing"); - // // self.get_inner_node(node_index) - // //}); - // let old_node = match mutations.get_inner_node(node_index) { - // Some(old_node) => { - // std::eprintln!("old node found in mutations, using that"); - // old_node - // }, - // None => self.get_inner_node(node_index), - // }; - // let new_node = if is_right { - // InnerNode { - // left: old_node.left, - // right: new_child_hash, - // } - // } else { - // InnerNode { - // left: new_child_hash, - // right: old_node.right, - // } - // }; - // if let Some(prospective_node) = mutations.get_inner_node_mut(node_index) { - // *prospective_node = new_node.clone(); - // } - // - // // The next iteration will operate on this node's new hash. - // new_child_hash = new_node.hash(); - // - // let &equivalent_empty_hash = EmptySubtreeRoots::entry(DEPTH, node_depth); - // if new_child_hash == equivalent_empty_hash { - // // If a subtree is empty, we can remove the inner node, since it's equal to the - // // default value. - // mutations.node_removals.push(node_index); - // } else { - // mutations.node_additions.push((node_index, new_node)); - // } - // } - // - // // Once we're at depth 0, the last node we made is the new root. - // mutations.new_root = new_child_hash; - // mutations.pair_insertions.push((key, value)); - //} - fn good_insert( &self, - mutations: &mut Muts, + mutations: &mut MutationSet, key: Self::Key, value: Self::Value, ) { @@ -316,8 +188,6 @@ pub(crate) trait SparseMerkleTree: Clone { return; } - std::eprintln!("{}: performing insert with key {key:?}", func!()); - let mut node_index = { let leaf_index: LeafIndex = Self::key_to_leaf_index(&key); NodeIndex::from(leaf_index) @@ -325,67 +195,22 @@ pub(crate) trait SparseMerkleTree: Clone { let mut control = self.clone(); control.apply_muts(mutations.clone()); - //control.insert(key.clone(), value.clone()); - //let existing_leaf = self.maybe_get_leaf(&key); - //let mut maybe_leaf = mutations.maybe_get_values(&key); - //assert!(matches!(maybe_leaf.len(), 0 | 1)); - //let maybe_leaf = maybe_leaf.pop(); - //let existing_leaf = match maybe_leaf { - // Some(existing_value) => { - // let prospective_leaf = - // self.get_prospective_leaf(existing_leaf.as_ref(), &key, &existing_value); - // assert_eq!(existing_leaf, None); - // Some(prospective_leaf) - // }, - // None => existing_leaf, - //}; - // - //let new_child = self.get_prospective_leaf(existing_leaf.as_ref(), &key, &value); - //assert_eq!(self.maybe_get_leaf(&key), None, "key {key:?} already has values?"); - //let new_leaf = self.get_prospective_leaf(None, &key, &value); let old_leaf = mutations.maybe_get_leaf(self, &key); assert_eq!(control.maybe_get_leaf(&key), old_leaf); - if mutations.pair_insertions.is_empty() { - std::eprintln!( - "no insertions yet, our current leaf is {:?}", - self.maybe_get_leaf(&key) - ); - } let new_leaf = self.get_prospective_leaf(old_leaf.as_ref(), &key, &value); let leaf_hash = Self::hash_leaf(&new_leaf); assert_eq!(control.hash_prospective_leaf(&key, &value), leaf_hash); let mut new_child_hash = leaf_hash; // Prospective values for this key. - //let prospective_values = mutations.maybe_get_values(&key); - //assert_eq!(prospective_values.len(), 0); - //let new_leaf = match mutations.maybe_get_values(&key) { - // - //} - - //let ref control_leaf = control.get_leaf(&key); - //assert_eq!(control_leaf, &existing_leaf.unwrap()); - //let control_hash = Self::hash_leaf(control_leaf); - //assert_eq!(control_hash, new_child_hash); - // - //assert_eq!(control_leaf, &new_child); - for node_depth in (0..node_index.depth()).rev() { let is_right = node_index.is_value_odd(); node_index.move_up(); - let old_node = match mutations.get_inner_node(node_index) { - Some(prospective) => { - //let existing = self.get_inner_node(node_index); - //let &equivalent_empty = EmptySubtreeRoots::entry(DEPTH, node_depth); - //if existing.hash() != equivalent_empty && existing != prospective { - // //assert_eq!(existing, prospective); - //} - prospective - }, - None => self.get_inner_node(node_index), - }; + let old_node = mutations + .get_inner_node(node_index) + .unwrap_or_else(|| self.get_inner_node(node_index)); assert_eq!(control.get_inner_node(node_index), old_node); let new_node = if is_right { @@ -406,12 +231,6 @@ pub(crate) trait SparseMerkleTree: Clone { control.apply_muts(mutations); let control_old_node = control.get_inner_node(node_index); assert_eq!(control_old_node, old_node); - - //control.insert(key.clone(), value.clone()); - //let control_leaf = control.get_leaf(&key); - //assert_eq!(control_leaf, new_leaf); - //let control_new_node = control.get_inner_node(node_index); - //assert_eq!(control_new_node, new_node); } let mut modified_control = control.clone(); @@ -421,16 +240,12 @@ pub(crate) trait SparseMerkleTree: Clone { // The next iteration will operate on this node's new hash. new_child_hash = new_node.hash(); - std::eprintln!("\n{}: new_child_hash={new_child_hash:?}", func!()); let &equivalent_empty_hash = EmptySubtreeRoots::entry(DEPTH, node_depth); if new_child_hash == equivalent_empty_hash { mutations.maybe_remove_node(node_index); - - //mutations.mutations.push(Mutation::Removal(node_index)); - //std::eprintln!("did removal do something? {did_change}"); } else { - mutations.maybe_insert_inner_node(node_index, new_node); + mutations.insert_inner_node(node_index, new_node); let leaf_index = NodeIndex::from(Self::key_to_leaf_index(&key)); let leaf_parent = mutations.get_inner_node(leaf_index.as_up()).unwrap(); @@ -452,45 +267,25 @@ pub(crate) trait SparseMerkleTree: Clone { assert_eq!(control.root(), mutations.new_root); } - fn start_muts(&self) -> Muts { - Muts:: { - //mutations: Default::default(), + fn start_muts(&self) -> MutationSet { + MutationSet:: { node_mutations: Default::default(), pair_insertions: Default::default(), new_root: self.root(), } } - //fn apply_mutations(&mut self, mut mutations: Mutations) { - // for (key, value) in mutations.pair_insertions.drain(..) { - // self.insert_value(key, value); - // } - // - // for index in mutations.node_removals.drain(..) { - // self.remove_inner_node(index); - // } - // - // for (index, new_node) in mutations.node_additions.drain(..) { - // self.insert_inner_node(index, new_node); - // } - // - // self.set_root(mutations.new_root); - //} - - fn apply_muts(&mut self, mutations: Muts) { + fn apply_muts(&mut self, mutations: MutationSet) { use NodeMutation::*; - let Muts { + let MutationSet { node_mutations, pair_insertions, new_root, } = mutations; - #[cfg(any(debug_assertions, test))] let mut control = self.clone(); - if cfg!(any(debug_assertions, test)) { - for (key, value) in pair_insertions.iter().cloned() { - control.insert(key, value); - } + for (key, value) in pair_insertions.iter().cloned() { + control.insert(key, value); } for (index, mutation) in node_mutations.into_iter() { @@ -498,36 +293,13 @@ pub(crate) trait SparseMerkleTree: Clone { Removal => self.remove_inner_node(index), Addition(node) => self.insert_inner_node(index, node), } - //if cfg!(any(debug_assertions, test)) { - // let control_node = control.get_inner_node(index); - // let test_node = self.get_inner_node(index); - // assert_eq!(control_node, test_node); - //} } for (key, value) in pair_insertions.into_iter() { self.insert_value(key, value); } self.set_root(new_root); - if cfg!(any(debug_assertions, test)) { - assert_eq!(control.root(), self.root()); - } - //for mutation in mutations.node_mutations.drain(..) { - // match mutation { - // Removal(idx) => self.remove_inner_node(idx), - // Addition(idx, node) - // } - //} - //use Mutation::*; - //for mutation in mutations.mutations.drain(..) { - // match mutation { - // Removal(idx) => self.remove_inner_node(idx), - // Addition(idx, node) => self.insert_inner_node(idx, node), - // PairInsertion(key, value) => { - // self.insert_value(key, value); - // }, - // } - //} + assert_eq!(control.root(), self.root()); } /// Recomputes the branch nodes (including the root) from `index` all the way to the root. @@ -688,192 +460,83 @@ impl TryFrom for LeafIndex { } } -// MUTATIONS -//#[derive(Debug, Clone, PartialEq)] -//#[cfg(not(test))] -//pub enum Mutation { -// Removal(NodeIndex), -// Addition(NodeIndex, InnerNode), -// PairInsertion(K, V), -//} - -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum NodeMutation { Removal, Addition(InnerNode), } -#[derive(Debug, Clone, PartialEq)] -pub struct Muts { - //mutations: Vec>, +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct MutationSet +where + T: SparseMerkleTree + Clone, +{ node_mutations: BTreeMap, - pair_insertions: Vec<(K, V)>, + pair_insertions: Vec<(T::Key, T::Value)>, new_root: RpoDigest, } -#[derive(Debug, Clone, PartialEq)] -pub struct MaybeNode { - inner: Option, - index: NodeIndex, -} -impl MaybeNode { - pub fn from(inner: InnerNode, index: NodeIndex) -> Self { - Self { inner: Some(inner), index } - } - - pub fn new_empty(index: NodeIndex) -> Self { - Self { inner: None, index } - } - - pub fn or_empty(self) -> InnerNode { - match self.inner { - Some(node) => node, - None => { - let &child = EmptySubtreeRoots::entry(DEPTH, self.index.depth() + 1); - InnerNode { left: child, right: child } - }, - } - } -} - -impl Muts { - fn maybe_get_values(&self, key: &K) -> Vec { - self.pair_insertions - .iter() - .filter_map(|(cur_key, cur_value)| if cur_key == key { Some(cur_value) } else { None }) - .cloned() - .collect() - } - - fn maybe_get_leaf(&self, tree: &T, key: &K) -> Option - where - T: SparseMerkleTree, - { +impl MutationSet +where + T: SparseMerkleTree, +{ + fn maybe_get_leaf(&self, tree: &T, key: &T::Key) -> Option { + std::eprintln!("BEGIN"); let leaf_index = T::key_to_leaf_index(key); let pairs_at_index = self .pair_insertions .iter() .filter(|&pair| T::key_to_leaf_index(&pair.0) == leaf_index); - let inital_acc: Option = tree.maybe_get_leaf(&key); + let inital_acc = tree.maybe_get_leaf(&key); + let mut iteration: u32 = 0; let leaf = pairs_at_index.fold(inital_acc, |acc, (k, v)| { - // - Some(tree.get_prospective_leaf(acc.as_ref(), k, v)) + std::eprintln!(" iteration {iteration}"); + iteration += 1; + let existing_leaf = acc.as_ref(); + Some(tree.get_prospective_leaf(existing_leaf, k, v)) }); + std::eprintln!("END"); + leaf } fn get_inner_node(&self, index: NodeIndex) -> Option { use NodeMutation::*; - match self.node_mutations.get(&index) { - Some(Addition(node)) => Some(node.clone()), - Some(Removal) => { - //std::eprintln!("{}: found other mutation? wat do. {other:?}", func!()); - //panic!(); - //let &empty_child_hash = EmptySubtreeRoots::entry(DEPTH, index.depth()); - let node = EmptySubtreeRoots::entry(DEPTH, index.depth() + 1); - Some(InnerNode { left: *node, right: *node }) + self.node_mutations.get(&index).map(|mutation| match mutation { + Addition(node) => node.clone(), + Removal => { + let &child = EmptySubtreeRoots::entry(DEPTH, index.depth() + 1); + InnerNode { left: child, right: child } }, - None => None, - } - - //use Mutation::*; - //self.mutations.iter().find_map(|mutation| match mutation { - // Addition(idx, node) if *idx == index => Some(node.clone()), - // _ => None, - //}) + }) } - fn maybe_get_node(&self, index: NodeIndex) -> MaybeNode { + pub fn insert_inner_node(&mut self, index: NodeIndex, new_node: InnerNode) { + use Entry::*; use NodeMutation::*; - match self.node_mutations.get(&index) { - Some(Addition(node)) => MaybeNode::from(node.clone(), index), - Some(Removal) => { - MaybeNode::from(MaybeNode:: { inner: None, index }.or_empty(), index) - }, - None => MaybeNode::new_empty(index), - } - } - - fn get_inner_node_mut(&mut self, index: NodeIndex) -> Option<&mut InnerNode> { - //use Mutation::*; - use NodeMutation::*; - //self.mutations.iter_mut().find_map(|mutation| match mutation { - // Addition(idx, node) if *idx == index => Some(node), - // Removal(idx) if *idx == index => { - // panic!(); - // }, - // _ => None, - //}) - match self.node_mutations.get_mut(&index) { - Some(Addition(node)) => Some(node), - _ => None, - } - } - - pub fn maybe_insert_inner_node(&mut self, index: NodeIndex, node: InnerNode) -> bool { - //use Mutation::*; - use NodeMutation::*; - - std::eprintln!( - "attempting to insert inner node at {index:?}, with {} mutations", - self.node_mutations.len() - ); - - let mut mutated: bool = false; - //let mut found_existing: bool = false; // XXX - let orig = node.clone(); + let orig = new_node.clone(); - let mut node = Some(node); - - use Entry::*; match self.node_mutations.entry(index) { Vacant(entry) => { - let node = node.take().unwrap(); - std::eprintln!("{}: normal insert", func!()); - entry.insert(Addition(node)); + entry.insert(Addition(new_node)); }, Occupied(mut entry) => match entry.get_mut() { - Addition(ref existing) if Some(existing) == node.as_ref() => { - std::eprintln!("{}: existing entry is identical; doing nothing", func!()); - }, Addition(existing) => { - let node = node.take().unwrap(); - std::eprintln!( - "{}: modifying existing addition entry from {:?} to {:?}", - func!(), - existing.hash(), - node.hash() - ); - mutated = true; - *existing = node; + // If there's an existing addition with this key, then overwrite it to be an + // addition of this new node instead. + *existing = new_node; }, Removal => { - std::eprintln!("{}: removal found; changing to addition", func!()); - mutated = true; - entry.insert(Addition(node.take().unwrap())); + // Likewise a removal of this key gets overwritten with an addition. + entry.insert(Addition(new_node)); }, }, }; - std::eprintln!(""); - - //match self.node_mutations.get_mut(&index) { - // Some(mutation) => match mutation { - // Addition(existing) => { - // *existing = node.take().unwrap(); - // found_existing = true; - // mutated = true; - // }, - // Removal(existing) => { - // self.node_mutations.remove() - // } - // }, - //}; - // XXX: sanity check match self.get_inner_node(index) { Some(inserted) => assert_eq!(orig, inserted), @@ -883,67 +546,23 @@ impl Muts { assert_eq!(orig, node); }, }; - - mutated - - //self.mutations.retain_mut(|mutation: &mut Mutation<_, _>| match mutation { - // Removal(idx) if *idx == index => { - // mutated = true; - // std::eprintln!("maybe_insert_node(): found removal at same index, removing"); - // false - // }, - // Addition(idx, cur_node) => { - // // FIXME: unnecessary clones - // if Some(cur_node.clone()) == node.as_mut().cloned() { - // found_existing = true; - // std::eprintln!("maybe_insert_node(): found identical addition, ignoring"); - // panic!(); - // } else if *idx == index { - // mutated = true; - // std::eprintln!( - // "maybe_insert_node(): found different addition at same index, replacing" - // ); - // *cur_node = node.take().unwrap(); // XXX - // } - // true - // }, - // _ => true, - //}); - // - //if !mutated && !found_existing { - // mutated = true; - // self.mutations.push(Addition(index, node.take().unwrap())); - //} - //mutated } - pub fn maybe_remove_node(&mut self, index: NodeIndex) -> bool { - use NodeMutation::*; - std::eprintln!( - "attempting to remove inner node at {index:?} with {} mutations", - self.node_mutations.len() - ); - - let mut mutated: bool = false; - + pub fn maybe_remove_node(&mut self, index: NodeIndex) { use Entry::*; + use NodeMutation::*; + match self.node_mutations.entry(index) { Vacant(entry) => { - std::eprintln!("{}: normal removal", func!()); - mutated = true; entry.insert(Removal); }, Occupied(mut entry) => match entry.get_mut() { Addition(_) => { - std::eprintln!("{}: found addition; changing to removal", func!()); - mutated = true; entry.insert(Removal); }, - Removal => { - std::eprintln!("{}: identical to existing removal; doing nothing", func!()); - }, + Removal => (), }, - }; + } // XXX: sanity check match self.get_inner_node(index) { @@ -955,72 +574,80 @@ impl Muts { }, None => (), }; + } - mutated + pub fn insert(&mut self, tree: &T, key: T::Key, value: T::Value) { + // This functions calculations are eager. Future work could make them lazy? - // use Mutation::*; - // - // let mut mutated: bool = false; - // let mut found_existing: bool = false; - // - // self.mutations.retain_mut(|mutation: &mut Mutation<_, _>| match mutation { - // Removal(idx) if *idx == index => { - // found_existing = true; - // std::eprintln!( - // "maybe_remove_node(): found a removal with same index, doing nothing" - // ); - // true - // }, - // Addition(idx, _) if *idx == index => { - // mutated = true; - // std::eprintln!("maybe_remove_node(): found an addition with same index, removing."); - // false - // }, - // _ => true, - // }); - // - // if !found_existing { - // mutated = true; - // std::eprintln!("maybe_remove_node(): pushing Removal"); - // self.mutations.push(Removal(index)); - // } - // mutated + let old_value = tree.get_value(&key); + if value == old_value { + return; + } + + let mut node_index = { + let leaf_index: LeafIndex = T::key_to_leaf_index(&key); + NodeIndex::from(leaf_index) + }; + + let old_leaf = self.maybe_get_leaf(tree, &key); + let new_leaf = tree.get_prospective_leaf(old_leaf.as_ref(), &key, &value); + + let mut new_child_hash = T::hash_leaf(&new_leaf); + + for node_depth in (0..node_index.depth()).rev() { + let is_right = node_index.is_value_odd(); + node_index.move_up(); + + let old_node = self + .get_inner_node(node_index) + .unwrap_or_else(|| tree.get_inner_node(node_index)); + + let new_node = if is_right { + InnerNode { + left: old_node.left, + right: new_child_hash, + } + } else { + InnerNode { + left: new_child_hash, + right: old_node.right, + } + }; + + // The next iteration will operate on this new node's new. + new_child_hash = new_node.hash(); + + let &equivalent_empty_hash = EmptySubtreeRoots::entry(DEPTH, node_depth); + if new_child_hash == equivalent_empty_hash { + self.maybe_remove_node(node_index); + } else { + self.insert_inner_node(node_index, new_node); + } + } + // Once we're at depth 0, the last node we made is the new root. + self.new_root = new_child_hash; + + self.pair_insertions.push((key, value)); + } + + pub fn apply(self, tree: &mut T) { + use NodeMutation::*; + let MutationSet { + node_mutations, + pair_insertions, + new_root, + } = self; + + for (index, mutation) in node_mutations { + match mutation { + Removal => tree.remove_inner_node(index), + Addition(node) => tree.insert_inner_node(index, node), + } + } + for (key, value) in pair_insertions { + tree.insert_value(key, value); + } + + tree.set_root(new_root); } } - -//#[derive(Debug, Clone, PartialEq)] -//pub struct Mutations { -// node_removals: Vec, -// node_additions: Vec<(NodeIndex, InnerNode)>, -// pair_insertions: Vec<(K, V)>, -// new_root: RpoDigest, -//} -// -//impl Mutations { -// pub fn new() -> Self { -// Mutations { -// node_removals: vec![], -// node_additions: vec![], -// pair_insertions: vec![], -// new_root: Default::default(), -// } -// } -// -// pub fn get_inner_node(&self, index: NodeIndex) -> Option { -// self.node_additions -// .iter() -// .find(|(idx, _)| *idx == index) -// .map(|(_, node)| node.clone()) -// //.unwrap_or_else(|| { -// // let &child = EmptySubtreeRoots::entry(DEPTH, index.depth() + 1); -// // InnerNode { left: child, right: child } -// //}) -// } -// -// pub fn get_inner_node_mut(&mut self, index: NodeIndex) -> Option<&mut InnerNode> { -// self.node_additions -// .iter_mut() -// .find(|(idx, _)| *idx == index) -// .map(|(_, node)| node) -// } -//}