Browse Source

feat: add EMPTY_VALUE const to SMTs

al-gkr-basic-workflow
Bobbin Threadbare 1 year ago
parent
commit
4215e83ae5
2 changed files with 17 additions and 11 deletions
  1. +8
    -5
      src/merkle/simple_smt/mod.rs
  2. +9
    -6
      src/merkle/tiered_smt/mod.rs

+ 8
- 5
src/merkle/simple_smt/mod.rs

@ -1,6 +1,6 @@
use super::{ use super::{
empty_roots::EMPTY_WORD, BTreeMap, BTreeSet, EmptySubtreeRoots, InnerNodeInfo, MerkleError,
MerklePath, NodeIndex, Rpo256, RpoDigest, Vec, Word,
BTreeMap, BTreeSet, EmptySubtreeRoots, InnerNodeInfo, MerkleError, MerklePath, NodeIndex,
Rpo256, RpoDigest, Vec, Word,
}; };
#[cfg(test)] #[cfg(test)]
@ -31,6 +31,9 @@ impl SimpleSmt {
/// Maximum supported depth. /// Maximum supported depth.
pub const MAX_DEPTH: u8 = 64; pub const MAX_DEPTH: u8 = 64;
/// Value of an empty leaf.
pub const EMPTY_VALUE: Word = super::empty_roots::EMPTY_WORD;
// CONSTRUCTORS // CONSTRUCTORS
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
@ -91,12 +94,12 @@ impl SimpleSmt {
let mut empty_entries = BTreeSet::new(); let mut empty_entries = BTreeSet::new();
for (key, value) in entries { for (key, value) in entries {
let old_value = tree.update_leaf(key, value)?; let old_value = tree.update_leaf(key, value)?;
if old_value != EMPTY_WORD || empty_entries.contains(&key) {
if old_value != Self::EMPTY_VALUE || empty_entries.contains(&key) {
return Err(MerkleError::DuplicateValuesForIndex(key)); return Err(MerkleError::DuplicateValuesForIndex(key));
} }
// if we've processed an empty entry, add the key to the set of empty entry keys, and // if we've processed an empty entry, add the key to the set of empty entry keys, and
// if this key was already in the set, return an error // if this key was already in the set, return an error
if value == EMPTY_WORD && !empty_entries.insert(key) {
if value == Self::EMPTY_VALUE && !empty_entries.insert(key) {
return Err(MerkleError::DuplicateValuesForIndex(key)); return Err(MerkleError::DuplicateValuesForIndex(key));
} }
} }
@ -210,7 +213,7 @@ impl SimpleSmt {
/// # Errors /// # Errors
/// Returns an error if the index is greater than the maximum tree capacity, that is 2^{depth}. /// Returns an error if the index is greater than the maximum tree capacity, that is 2^{depth}.
pub fn update_leaf(&mut self, index: u64, value: Word) -> Result<Word, MerkleError> { pub fn update_leaf(&mut self, index: u64, value: Word) -> Result<Word, MerkleError> {
let old_value = self.insert_leaf_node(index, value).unwrap_or(EMPTY_WORD);
let old_value = self.insert_leaf_node(index, value).unwrap_or(Self::EMPTY_VALUE);
// if the old value and new value are the same, there is nothing to update // if the old value and new value are the same, there is nothing to update
if value == old_value { if value == old_value {

+ 9
- 6
src/merkle/tiered_smt/mod.rs

@ -1,6 +1,6 @@
use super::{ use super::{
empty_roots::EMPTY_WORD, BTreeMap, BTreeSet, EmptySubtreeRoots, Felt, InnerNodeInfo,
MerkleError, MerklePath, NodeIndex, Rpo256, RpoDigest, StarkField, Vec, Word, ZERO,
BTreeMap, BTreeSet, EmptySubtreeRoots, Felt, InnerNodeInfo, MerkleError, MerklePath, NodeIndex,
Rpo256, RpoDigest, StarkField, Vec, Word, ZERO,
}; };
use core::cmp; use core::cmp;
@ -54,6 +54,9 @@ impl TieredSmt {
/// Maximum node depth. This is also the bottom tier of the tree. /// Maximum node depth. This is also the bottom tier of the tree.
const MAX_DEPTH: u8 = 64; const MAX_DEPTH: u8 = 64;
/// Value of an empty leaf.
pub const EMPTY_VALUE: Word = super::empty_roots::EMPTY_WORD;
// CONSTRUCTORS // CONSTRUCTORS
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
@ -74,12 +77,12 @@ impl TieredSmt {
let mut empty_entries = BTreeSet::new(); let mut empty_entries = BTreeSet::new();
for (key, value) in entries { for (key, value) in entries {
let old_value = tree.insert(key, value); let old_value = tree.insert(key, value);
if old_value != EMPTY_WORD || empty_entries.contains(&key) {
if old_value != Self::EMPTY_VALUE || empty_entries.contains(&key) {
return Err(MerkleError::DuplicateValuesForKey(key)); return Err(MerkleError::DuplicateValuesForKey(key));
} }
// if we've processed an empty entry, add the key to the set of empty entry keys, and // if we've processed an empty entry, add the key to the set of empty entry keys, and
// if this key was already in the set, return an error // if this key was already in the set, return an error
if value == EMPTY_WORD && !empty_entries.insert(key) {
if value == Self::EMPTY_VALUE && !empty_entries.insert(key) {
return Err(MerkleError::DuplicateValuesForKey(key)); return Err(MerkleError::DuplicateValuesForKey(key));
} }
} }
@ -136,7 +139,7 @@ impl TieredSmt {
pub fn get_value(&self, key: RpoDigest) -> Word { pub fn get_value(&self, key: RpoDigest) -> Word {
match self.values.get(&key) { match self.values.get(&key) {
Some(value) => *value, Some(value) => *value,
None => EMPTY_WORD,
None => Self::EMPTY_VALUE,
} }
} }
@ -149,7 +152,7 @@ impl TieredSmt {
/// If the value for the specified key was not previously set, [ZERO; 4] is returned. /// If the value for the specified key was not previously set, [ZERO; 4] is returned.
pub fn insert(&mut self, key: RpoDigest, value: Word) -> Word { pub fn insert(&mut self, key: RpoDigest, value: Word) -> Word {
// insert the value into the key-value map, and if nothing has changed, return // insert the value into the key-value map, and if nothing has changed, return
let old_value = self.values.insert(key, value).unwrap_or(EMPTY_WORD);
let old_value = self.values.insert(key, value).unwrap_or(Self::EMPTY_VALUE);
if old_value == value { if old_value == value {
return old_value; return old_value;
} }

Loading…
Cancel
Save