miden_crypto/merkle/smt/
mod.rs

1use alloc::vec::Vec;
2use core::hash::Hash;
3
4use winter_utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
5
6use super::{EmptySubtreeRoots, InnerNodeInfo, MerkleError, MerklePath, NodeIndex};
7use crate::{
8    EMPTY_WORD, Felt, Word,
9    hash::rpo::{Rpo256, RpoDigest},
10};
11
12mod full;
13pub use full::{SMT_DEPTH, Smt, SmtLeaf, SmtLeafError, SmtProof, SmtProofError};
14#[cfg(feature = "internal")]
15pub use full::{SubtreeLeaf, build_subtree_for_bench};
16
17mod simple;
18pub use simple::SimpleSmt;
19
20mod partial;
21pub use partial::PartialSmt;
22
23// CONSTANTS
24// ================================================================================================
25
26/// Minimum supported depth.
27pub const SMT_MIN_DEPTH: u8 = 1;
28
29/// Maximum supported depth.
30pub const SMT_MAX_DEPTH: u8 = 64;
31
32// SPARSE MERKLE TREE
33// ================================================================================================
34
35/// A map whose keys are not guarantied to be ordered.
36#[cfg(feature = "smt_hashmaps")]
37type UnorderedMap<K, V> = hashbrown::HashMap<K, V>;
38#[cfg(not(feature = "smt_hashmaps"))]
39type UnorderedMap<K, V> = alloc::collections::BTreeMap<K, V>;
40type InnerNodes = UnorderedMap<NodeIndex, InnerNode>;
41type Leaves<T> = UnorderedMap<u64, T>;
42type NodeMutations = UnorderedMap<NodeIndex, NodeMutation>;
43
44/// An abstract description of a sparse Merkle tree.
45///
46/// A sparse Merkle tree is a key-value map which also supports proving that a given value is indeed
47/// stored at a given key in the tree. It is viewed as always being fully populated. If a leaf's
48/// value was not explicitly set, then its value is the default value. Typically, the vast majority
49/// of leaves will store the default value (hence it is "sparse"), and therefore the internal
50/// representation of the tree will only keep track of the leaves that have a different value from
51/// the default.
52///
53/// All leaves sit at the same depth. The deeper the tree, the more leaves it has; but also the
54/// longer its proofs are - of exactly `log(depth)` size. A tree cannot have depth 0, since such a
55/// tree is just a single value, and is probably a programming mistake.
56///
57/// Every key maps to one leaf. If there are as many keys as there are leaves, then
58/// [Self::Leaf] should be the same type as [Self::Value], as is the case with
59/// [crate::merkle::SimpleSmt]. However, if there are more keys than leaves, then [`Self::Leaf`]
60/// must accommodate all keys that map to the same leaf.
61///
62/// [SparseMerkleTree] currently doesn't support optimizations that compress Merkle proofs.
63pub(crate) trait SparseMerkleTree<const DEPTH: u8> {
64    /// The type for a key
65    type Key: Clone + Ord + Eq + Hash;
66    /// The type for a value
67    type Value: Clone + PartialEq;
68    /// The type for a leaf
69    type Leaf: Clone;
70    /// The type for an opening (i.e. a "proof") of a leaf
71    type Opening;
72
73    /// The default value used to compute the hash of empty leaves
74    const EMPTY_VALUE: Self::Value;
75
76    /// The root of the empty tree with provided DEPTH
77    const EMPTY_ROOT: RpoDigest;
78
79    // PROVIDED METHODS
80    // ---------------------------------------------------------------------------------------------
81
82    /// Returns an opening of the leaf associated with `key`. Conceptually, an opening is a Merkle
83    /// path to the leaf, as well as the leaf itself.
84    fn open(&self, key: &Self::Key) -> Self::Opening {
85        let leaf = self.get_leaf(key);
86
87        let mut index: NodeIndex = {
88            let leaf_index: LeafIndex<DEPTH> = Self::key_to_leaf_index(key);
89            leaf_index.into()
90        };
91
92        let merkle_path = {
93            let mut path = Vec::with_capacity(index.depth() as usize);
94            for _ in 0..index.depth() {
95                let is_right = index.is_value_odd();
96                index.move_up();
97                let InnerNode { left, right } = self.get_inner_node(index);
98                let value = if is_right { left } else { right };
99                path.push(value);
100            }
101
102            MerklePath::new(path)
103        };
104
105        Self::path_and_leaf_to_opening(merkle_path, leaf)
106    }
107
108    /// Inserts a value at the specified key, returning the previous value associated with that key.
109    /// Recall that by definition, any key that hasn't been updated is associated with
110    /// [`Self::EMPTY_VALUE`].
111    ///
112    /// This also recomputes all hashes between the leaf (associated with the key) and the root,
113    /// updating the root itself.
114    fn insert(&mut self, key: Self::Key, value: Self::Value) -> Self::Value {
115        let old_value = self.insert_value(key.clone(), value.clone()).unwrap_or(Self::EMPTY_VALUE);
116
117        // if the old value and new value are the same, there is nothing to update
118        if value == old_value {
119            return value;
120        }
121
122        let leaf = self.get_leaf(&key);
123        let node_index = {
124            let leaf_index: LeafIndex<DEPTH> = Self::key_to_leaf_index(&key);
125            leaf_index.into()
126        };
127
128        self.recompute_nodes_from_index_to_root(node_index, Self::hash_leaf(&leaf));
129
130        old_value
131    }
132
133    /// Recomputes the branch nodes (including the root) from `index` all the way to the root.
134    /// `node_hash_at_index` is the hash of the node stored at index.
135    fn recompute_nodes_from_index_to_root(
136        &mut self,
137        mut index: NodeIndex,
138        node_hash_at_index: RpoDigest,
139    ) {
140        let mut node_hash = node_hash_at_index;
141        for node_depth in (0..index.depth()).rev() {
142            let is_right = index.is_value_odd();
143            index.move_up();
144            let InnerNode { left, right } = self.get_inner_node(index);
145            let (left, right) = if is_right {
146                (left, node_hash)
147            } else {
148                (node_hash, right)
149            };
150            node_hash = Rpo256::merge(&[left, right]);
151
152            if node_hash == *EmptySubtreeRoots::entry(DEPTH, node_depth) {
153                // If a subtree is empty, then can remove the inner node, since it's equal to the
154                // default value
155                self.remove_inner_node(index);
156            } else {
157                self.insert_inner_node(index, InnerNode { left, right });
158            }
159        }
160        self.set_root(node_hash);
161    }
162
163    /// Computes what changes are necessary to insert the specified key-value pairs into this Merkle
164    /// tree, allowing for validation before applying those changes.
165    ///
166    /// This method returns a [`MutationSet`], which contains all the information for inserting
167    /// `kv_pairs` into this Merkle tree already calculated, including the new root hash, which can
168    /// be queried with [`MutationSet::root()`]. Once a mutation set is returned,
169    /// [`SparseMerkleTree::apply_mutations()`] can be called in order to commit these changes to
170    /// the Merkle tree, or [`drop()`] to discard them.
171    fn compute_mutations(
172        &self,
173        kv_pairs: impl IntoIterator<Item = (Self::Key, Self::Value)>,
174    ) -> MutationSet<DEPTH, Self::Key, Self::Value> {
175        self.compute_mutations_sequential(kv_pairs)
176    }
177
178    /// Sequential version of [`SparseMerkleTree::compute_mutations()`].
179    /// This is the default implementation.
180    fn compute_mutations_sequential(
181        &self,
182        kv_pairs: impl IntoIterator<Item = (Self::Key, Self::Value)>,
183    ) -> MutationSet<DEPTH, Self::Key, Self::Value> {
184        use NodeMutation::*;
185
186        let mut new_root = self.root();
187        let mut new_pairs: UnorderedMap<Self::Key, Self::Value> = Default::default();
188        let mut node_mutations: NodeMutations = Default::default();
189
190        for (key, value) in kv_pairs {
191            // If the old value and the new value are the same, there is nothing to update.
192            // For the unusual case that kv_pairs has multiple values at the same key, we'll have
193            // to check the key-value pairs we've already seen to get the "effective" old value.
194            let old_value = new_pairs.get(&key).cloned().unwrap_or_else(|| self.get_value(&key));
195            if value == old_value {
196                continue;
197            }
198
199            let leaf_index = Self::key_to_leaf_index(&key);
200            let mut node_index = NodeIndex::from(leaf_index);
201
202            // We need the current leaf's hash to calculate the new leaf, but in the rare case that
203            // `kv_pairs` has multiple pairs that go into the same leaf, then those pairs are also
204            // part of the "current leaf".
205            let old_leaf = {
206                let pairs_at_index = new_pairs
207                    .iter()
208                    .filter(|&(new_key, _)| Self::key_to_leaf_index(new_key) == leaf_index);
209
210                pairs_at_index.fold(self.get_leaf(&key), |acc, (k, v)| {
211                    // Most of the time `pairs_at_index` should only contain a single entry (or
212                    // none at all), as multi-leaves should be really rare.
213                    let existing_leaf = acc.clone();
214                    self.construct_prospective_leaf(existing_leaf, k, v)
215                })
216            };
217
218            let new_leaf = self.construct_prospective_leaf(old_leaf, &key, &value);
219
220            let mut new_child_hash = Self::hash_leaf(&new_leaf);
221
222            for node_depth in (0..node_index.depth()).rev() {
223                // Whether the node we're replacing is the right child or the left child.
224                let is_right = node_index.is_value_odd();
225                node_index.move_up();
226
227                let old_node = node_mutations
228                    .get(&node_index)
229                    .map(|mutation| match mutation {
230                        Addition(node) => node.clone(),
231                        Removal => EmptySubtreeRoots::get_inner_node(DEPTH, node_depth),
232                    })
233                    .unwrap_or_else(|| self.get_inner_node(node_index));
234
235                let new_node = if is_right {
236                    InnerNode {
237                        left: old_node.left,
238                        right: new_child_hash,
239                    }
240                } else {
241                    InnerNode {
242                        left: new_child_hash,
243                        right: old_node.right,
244                    }
245                };
246
247                // The next iteration will operate on this new node's hash.
248                new_child_hash = new_node.hash();
249
250                let &equivalent_empty_hash = EmptySubtreeRoots::entry(DEPTH, node_depth);
251                let is_removal = new_child_hash == equivalent_empty_hash;
252                let new_entry = if is_removal { Removal } else { Addition(new_node) };
253                node_mutations.insert(node_index, new_entry);
254            }
255
256            // Once we're at depth 0, the last node we made is the new root.
257            new_root = new_child_hash;
258            // And then we're done with this pair; on to the next one.
259            new_pairs.insert(key, value);
260        }
261
262        MutationSet {
263            old_root: self.root(),
264            new_root,
265            node_mutations,
266            new_pairs,
267        }
268    }
269
270    /// Applies the prospective mutations computed with [`SparseMerkleTree::compute_mutations()`] to
271    /// this tree.
272    ///
273    /// # Errors
274    /// If `mutations` was computed on a tree with a different root than this one, returns
275    /// [`MerkleError::ConflictingRoots`] with a two-item [`Vec`]. The first item is the root hash
276    /// the `mutations` were computed against, and the second item is the actual current root of
277    /// this tree.
278    fn apply_mutations(
279        &mut self,
280        mutations: MutationSet<DEPTH, Self::Key, Self::Value>,
281    ) -> Result<(), MerkleError>
282    where
283        Self: Sized,
284    {
285        use NodeMutation::*;
286        let MutationSet {
287            old_root,
288            node_mutations,
289            new_pairs,
290            new_root,
291        } = mutations;
292
293        // Guard against accidentally trying to apply mutations that were computed against a
294        // different tree, including a stale version of this tree.
295        if old_root != self.root() {
296            return Err(MerkleError::ConflictingRoots {
297                expected_root: self.root(),
298                actual_root: old_root,
299            });
300        }
301
302        for (index, mutation) in node_mutations {
303            match mutation {
304                Removal => {
305                    self.remove_inner_node(index);
306                },
307                Addition(node) => {
308                    self.insert_inner_node(index, node);
309                },
310            }
311        }
312
313        for (key, value) in new_pairs {
314            self.insert_value(key, value);
315        }
316
317        self.set_root(new_root);
318
319        Ok(())
320    }
321
322    /// Applies the prospective mutations computed with [`SparseMerkleTree::compute_mutations()`] to
323    /// this tree and returns the reverse mutation set. Applying the reverse mutation sets to the
324    /// updated tree will revert the changes.
325    ///
326    /// # Errors
327    /// If `mutations` was computed on a tree with a different root than this one, returns
328    /// [`MerkleError::ConflictingRoots`] with a two-item [`Vec`]. The first item is the root hash
329    /// the `mutations` were computed against, and the second item is the actual current root of
330    /// this tree.
331    fn apply_mutations_with_reversion(
332        &mut self,
333        mutations: MutationSet<DEPTH, Self::Key, Self::Value>,
334    ) -> Result<MutationSet<DEPTH, Self::Key, Self::Value>, MerkleError>
335    where
336        Self: Sized,
337    {
338        use NodeMutation::*;
339        let MutationSet {
340            old_root,
341            node_mutations,
342            new_pairs,
343            new_root,
344        } = mutations;
345
346        // Guard against accidentally trying to apply mutations that were computed against a
347        // different tree, including a stale version of this tree.
348        if old_root != self.root() {
349            return Err(MerkleError::ConflictingRoots {
350                expected_root: self.root(),
351                actual_root: old_root,
352            });
353        }
354
355        let mut reverse_mutations = NodeMutations::new();
356        for (index, mutation) in node_mutations {
357            match mutation {
358                Removal => {
359                    if let Some(node) = self.remove_inner_node(index) {
360                        reverse_mutations.insert(index, Addition(node));
361                    }
362                },
363                Addition(node) => {
364                    if let Some(old_node) = self.insert_inner_node(index, node) {
365                        reverse_mutations.insert(index, Addition(old_node));
366                    } else {
367                        reverse_mutations.insert(index, Removal);
368                    }
369                },
370            }
371        }
372
373        let mut reverse_pairs = UnorderedMap::new();
374        for (key, value) in new_pairs {
375            if let Some(old_value) = self.insert_value(key.clone(), value) {
376                reverse_pairs.insert(key, old_value);
377            } else {
378                reverse_pairs.insert(key, Self::EMPTY_VALUE);
379            }
380        }
381
382        self.set_root(new_root);
383
384        Ok(MutationSet {
385            old_root: new_root,
386            node_mutations: reverse_mutations,
387            new_pairs: reverse_pairs,
388            new_root: old_root,
389        })
390    }
391
392    // REQUIRED METHODS
393    // ---------------------------------------------------------------------------------------------
394
395    /// Construct this type from already computed leaves and nodes. The caller ensures passed
396    /// arguments are correct and consistent with each other.
397    fn from_raw_parts(
398        inner_nodes: InnerNodes,
399        leaves: Leaves<Self::Leaf>,
400        root: RpoDigest,
401    ) -> Result<Self, MerkleError>
402    where
403        Self: Sized;
404
405    /// The root of the tree
406    fn root(&self) -> RpoDigest;
407
408    /// Sets the root of the tree
409    fn set_root(&mut self, root: RpoDigest);
410
411    /// Retrieves an inner node at the given index
412    fn get_inner_node(&self, index: NodeIndex) -> InnerNode;
413
414    /// Inserts an inner node at the given index
415    fn insert_inner_node(&mut self, index: NodeIndex, inner_node: InnerNode) -> Option<InnerNode>;
416
417    /// Removes an inner node at the given index
418    fn remove_inner_node(&mut self, index: NodeIndex) -> Option<InnerNode>;
419
420    /// Inserts a leaf node, and returns the value at the key if already exists
421    fn insert_value(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value>;
422
423    /// Returns the value at the specified key. Recall that by definition, any key that hasn't been
424    /// updated is associated with [`Self::EMPTY_VALUE`].
425    fn get_value(&self, key: &Self::Key) -> Self::Value;
426
427    /// Returns the leaf at the specified index.
428    fn get_leaf(&self, key: &Self::Key) -> Self::Leaf;
429
430    /// Returns the hash of a leaf
431    fn hash_leaf(leaf: &Self::Leaf) -> RpoDigest;
432
433    /// Returns what a leaf would look like if a key-value pair were inserted into the tree, without
434    /// mutating the tree itself. The existing leaf can be empty.
435    ///
436    /// To get a prospective leaf based on the current state of the tree, use `self.get_leaf(key)`
437    /// as the argument for `existing_leaf`. The return value from this function can be chained back
438    /// into this function as the first argument to continue making prospective changes.
439    ///
440    /// # Invariants
441    /// Because this method is for a prospective key-value insertion into a specific leaf,
442    /// `existing_leaf` must have the same leaf index as `key` (as determined by
443    /// [`SparseMerkleTree::key_to_leaf_index()`]), or the result will be meaningless.
444    fn construct_prospective_leaf(
445        &self,
446        existing_leaf: Self::Leaf,
447        key: &Self::Key,
448        value: &Self::Value,
449    ) -> Self::Leaf;
450
451    /// Maps a key to a leaf index
452    fn key_to_leaf_index(key: &Self::Key) -> LeafIndex<DEPTH>;
453
454    /// Maps a (MerklePath, Self::Leaf) to an opening.
455    ///
456    /// The length `path` is guaranteed to be equal to `DEPTH`
457    fn path_and_leaf_to_opening(path: MerklePath, leaf: Self::Leaf) -> Self::Opening;
458}
459
460// INNER NODE
461// ================================================================================================
462
463/// This struct is public so functions returning it can be used in `benches/`, but is otherwise not
464/// part of the public API.
465#[doc(hidden)]
466#[derive(Debug, Default, Clone, PartialEq, Eq)]
467#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
468pub struct InnerNode {
469    pub left: RpoDigest,
470    pub right: RpoDigest,
471}
472
473impl InnerNode {
474    pub fn hash(&self) -> RpoDigest {
475        Rpo256::merge(&[self.left, self.right])
476    }
477}
478
479// LEAF INDEX
480// ================================================================================================
481
482/// The index of a leaf, at a depth known at compile-time.
483#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
484#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
485pub struct LeafIndex<const DEPTH: u8> {
486    index: NodeIndex,
487}
488
489impl<const DEPTH: u8> LeafIndex<DEPTH> {
490    pub fn new(value: u64) -> Result<Self, MerkleError> {
491        if DEPTH < SMT_MIN_DEPTH {
492            return Err(MerkleError::DepthTooSmall(DEPTH));
493        }
494
495        Ok(LeafIndex { index: NodeIndex::new(DEPTH, value)? })
496    }
497
498    pub fn value(&self) -> u64 {
499        self.index.value()
500    }
501}
502
503impl LeafIndex<SMT_MAX_DEPTH> {
504    pub const fn new_max_depth(value: u64) -> Self {
505        LeafIndex {
506            index: NodeIndex::new_unchecked(SMT_MAX_DEPTH, value),
507        }
508    }
509}
510
511impl<const DEPTH: u8> From<LeafIndex<DEPTH>> for NodeIndex {
512    fn from(value: LeafIndex<DEPTH>) -> Self {
513        value.index
514    }
515}
516
517impl<const DEPTH: u8> TryFrom<NodeIndex> for LeafIndex<DEPTH> {
518    type Error = MerkleError;
519
520    fn try_from(node_index: NodeIndex) -> Result<Self, Self::Error> {
521        if node_index.depth() != DEPTH {
522            return Err(MerkleError::InvalidNodeIndexDepth {
523                expected: DEPTH,
524                provided: node_index.depth(),
525            });
526        }
527
528        Self::new(node_index.value())
529    }
530}
531
532impl<const DEPTH: u8> Serializable for LeafIndex<DEPTH> {
533    fn write_into<W: ByteWriter>(&self, target: &mut W) {
534        self.index.write_into(target);
535    }
536}
537
538impl<const DEPTH: u8> Deserializable for LeafIndex<DEPTH> {
539    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
540        Ok(Self { index: source.read()? })
541    }
542}
543
544// MUTATIONS
545// ================================================================================================
546
547/// A change to an inner node of a sparse Merkle tree that hasn't yet been applied.
548/// [`MutationSet`] stores this type in relation to a [`NodeIndex`] to keep track of what changes
549/// need to occur at which node indices.
550#[derive(Debug, Clone, PartialEq, Eq)]
551pub enum NodeMutation {
552    /// Node needs to be removed.
553    Removal,
554    /// Node needs to be inserted.
555    Addition(InnerNode),
556}
557
558/// Represents a group of prospective mutations to a `SparseMerkleTree`, created by
559/// `SparseMerkleTree::compute_mutations()`, and that can be applied with
560/// `SparseMerkleTree::apply_mutations()`.
561#[derive(Debug, Clone, Default, PartialEq, Eq)]
562pub struct MutationSet<const DEPTH: u8, K: Eq + Hash, V> {
563    /// The root of the Merkle tree this MutationSet is for, recorded at the time
564    /// [`SparseMerkleTree::compute_mutations()`] was called. Exists to guard against applying
565    /// mutations to the wrong tree or applying stale mutations to a tree that has since changed.
566    old_root: RpoDigest,
567    /// The set of nodes that need to be removed or added. The "effective" node at an index is the
568    /// Merkle tree's existing node at that index, with the [`NodeMutation`] in this map at that
569    /// index overlayed, if any. Each [`NodeMutation::Addition`] corresponds to a
570    /// [`SparseMerkleTree::insert_inner_node()`] call, and each [`NodeMutation::Removal`]
571    /// corresponds to a [`SparseMerkleTree::remove_inner_node()`] call.
572    node_mutations: NodeMutations,
573    /// The set of top-level key-value pairs we're prospectively adding to the tree, including
574    /// adding empty values. The "effective" value for a key is the value in this BTreeMap, falling
575    /// back to the existing value in the Merkle tree. Each entry corresponds to a
576    /// [`SparseMerkleTree::insert_value()`] call.
577    new_pairs: UnorderedMap<K, V>,
578    /// The calculated root for the Merkle tree, given these mutations. Publicly retrievable with
579    /// [`MutationSet::root()`]. Corresponds to a [`SparseMerkleTree::set_root()`]. call.
580    new_root: RpoDigest,
581}
582
583impl<const DEPTH: u8, K: Eq + Hash, V> MutationSet<DEPTH, K, V> {
584    /// Returns the SMT root that was calculated during `SparseMerkleTree::compute_mutations()`. See
585    /// that method for more information.
586    pub fn root(&self) -> RpoDigest {
587        self.new_root
588    }
589
590    /// Returns the SMT root before the mutations were applied.
591    pub fn old_root(&self) -> RpoDigest {
592        self.old_root
593    }
594
595    /// Returns the set of inner nodes that need to be removed or added.
596    pub fn node_mutations(&self) -> &NodeMutations {
597        &self.node_mutations
598    }
599
600    /// Returns the set of top-level key-value pairs that need to be added, updated or deleted
601    /// (i.e. set to `EMPTY_WORD`).
602    pub fn new_pairs(&self) -> &UnorderedMap<K, V> {
603        &self.new_pairs
604    }
605}
606
607// SERIALIZATION
608// ================================================================================================
609
610impl Serializable for InnerNode {
611    fn write_into<W: ByteWriter>(&self, target: &mut W) {
612        target.write(self.left);
613        target.write(self.right);
614    }
615}
616
617impl Deserializable for InnerNode {
618    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
619        let left = source.read()?;
620        let right = source.read()?;
621
622        Ok(Self { left, right })
623    }
624}
625
626impl Serializable for NodeMutation {
627    fn write_into<W: ByteWriter>(&self, target: &mut W) {
628        match self {
629            NodeMutation::Removal => target.write_bool(false),
630            NodeMutation::Addition(inner_node) => {
631                target.write_bool(true);
632                inner_node.write_into(target);
633            },
634        }
635    }
636}
637
638impl Deserializable for NodeMutation {
639    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
640        if source.read_bool()? {
641            let inner_node = source.read()?;
642            return Ok(NodeMutation::Addition(inner_node));
643        }
644
645        Ok(NodeMutation::Removal)
646    }
647}
648
649impl<const DEPTH: u8, K: Serializable + Eq + Hash, V: Serializable> Serializable
650    for MutationSet<DEPTH, K, V>
651{
652    fn write_into<W: ByteWriter>(&self, target: &mut W) {
653        target.write(self.old_root);
654        target.write(self.new_root);
655
656        let inner_removals: Vec<_> = self
657            .node_mutations
658            .iter()
659            .filter(|(_, value)| matches!(value, NodeMutation::Removal))
660            .map(|(key, _)| key)
661            .collect();
662        let inner_additions: Vec<_> = self
663            .node_mutations
664            .iter()
665            .filter_map(|(key, value)| match value {
666                NodeMutation::Addition(node) => Some((key, node)),
667                _ => None,
668            })
669            .collect();
670
671        target.write(inner_removals);
672        target.write(inner_additions);
673
674        target.write_usize(self.new_pairs.len());
675        target.write_many(&self.new_pairs);
676    }
677}
678
679impl<const DEPTH: u8, K: Deserializable + Ord + Eq + Hash, V: Deserializable> Deserializable
680    for MutationSet<DEPTH, K, V>
681{
682    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
683        let old_root = source.read()?;
684        let new_root = source.read()?;
685
686        let inner_removals: Vec<NodeIndex> = source.read()?;
687        let inner_additions: Vec<(NodeIndex, InnerNode)> = source.read()?;
688
689        let node_mutations = NodeMutations::from_iter(
690            inner_removals.into_iter().map(|index| (index, NodeMutation::Removal)).chain(
691                inner_additions
692                    .into_iter()
693                    .map(|(index, node)| (index, NodeMutation::Addition(node))),
694            ),
695        );
696
697        let num_new_pairs = source.read_usize()?;
698        let new_pairs = source.read_many(num_new_pairs)?;
699        let new_pairs = UnorderedMap::from_iter(new_pairs);
700
701        Ok(Self {
702            old_root,
703            node_mutations,
704            new_pairs,
705            new_root,
706        })
707    }
708}