Browse Source

feat: add `Smt::is_empty` (#337)

al-update-winterfell
Andrey Khmuro 6 months ago
committed by GitHub
parent
commit
940cc04670
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
6 changed files with 45 additions and 0 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +7
    -0
      src/merkle/smt/full/mod.rs
  3. +10
    -0
      src/merkle/smt/full/tests.rs
  4. +3
    -0
      src/merkle/smt/mod.rs
  5. +7
    -0
      src/merkle/smt/simple/mod.rs
  6. +17
    -0
      src/merkle/smt/simple/tests.rs

+ 1
- 0
CHANGELOG.md

@ -6,6 +6,7 @@
- Added `Smt::compute_mutations()` and `Smt::apply_mutations()` for validation-checked insertions (#327). - Added `Smt::compute_mutations()` and `Smt::apply_mutations()` for validation-checked insertions (#327).
- [BREAKING] Changed return value of the `Mmr::verify()` and `MerklePath::verify()` from `bool` to - [BREAKING] Changed return value of the `Mmr::verify()` and `MerklePath::verify()` from `bool` to
`Result<>` (#). `Result<>` (#).
- Added `is_empty()` functions to the `SimpleSmt` and `Smt` structures. Added `EMPTY_ROOT` constant to the `SparseMerkleTree` trait (#337).
## 0.10.1 (2024-09-13) ## 0.10.1 (2024-09-13)

+ 7
- 0
src/merkle/smt/full/mod.rs

@ -130,6 +130,12 @@ impl Smt {
<Self as SparseMerkleTree<SMT_DEPTH>>::open(self, key) <Self as SparseMerkleTree<SMT_DEPTH>>::open(self, key)
} }
/// Returns a boolean value indicating whether the SMT is empty.
pub fn is_empty(&self) -> bool {
debug_assert_eq!(self.leaves.is_empty(), self.root == Self::EMPTY_ROOT);
self.root == Self::EMPTY_ROOT
}
// ITERATORS // ITERATORS
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
@ -252,6 +258,7 @@ impl SparseMerkleTree for Smt {
type Opening = SmtProof; type Opening = SmtProof;
const EMPTY_VALUE: Self::Value = EMPTY_WORD; const EMPTY_VALUE: Self::Value = EMPTY_WORD;
const EMPTY_ROOT: RpoDigest = *EmptySubtreeRoots::entry(SMT_DEPTH, 0);
fn root(&self) -> RpoDigest { fn root(&self) -> RpoDigest {
self.root self.root

+ 10
- 0
src/merkle/smt/full/tests.rs

@ -516,6 +516,16 @@ fn test_smt_entries() {
assert!(entries.next().is_none()); assert!(entries.next().is_none());
} }
/// Tests that `EMPTY_ROOT` constant generated in the `Smt` equals to the root of the empty tree of
/// depth 64
#[test]
fn test_smt_check_empty_root_constant() {
// get the root of the empty tree of depth 64
let empty_root_64_depth = EmptySubtreeRoots::empty_hashes(64)[0];
assert_eq!(empty_root_64_depth, Smt::EMPTY_ROOT);
}
// SMT LEAF // SMT LEAF
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------

+ 3
- 0
src/merkle/smt/mod.rs

@ -56,6 +56,9 @@ pub(crate) trait SparseMerkleTree {
/// The default value used to compute the hash of empty leaves /// The default value used to compute the hash of empty leaves
const EMPTY_VALUE: Self::Value; const EMPTY_VALUE: Self::Value;
/// The root of the empty tree with provided DEPTH
const EMPTY_ROOT: RpoDigest;
// PROVIDED METHODS // PROVIDED METHODS
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------

+ 7
- 0
src/merkle/smt/simple/mod.rs

@ -158,6 +158,12 @@ impl SimpleSmt {
<Self as SparseMerkleTree<DEPTH>>::open(self, key) <Self as SparseMerkleTree<DEPTH>>::open(self, key)
} }
/// Returns a boolean value indicating whether the SMT is empty.
pub fn is_empty(&self) -> bool {
debug_assert_eq!(self.leaves.is_empty(), self.root == Self::EMPTY_ROOT);
self.root == Self::EMPTY_ROOT
}
// ITERATORS // ITERATORS
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
@ -298,6 +304,7 @@ impl SparseMerkleTree for SimpleSmt {
type Opening = ValuePath; type Opening = ValuePath;
const EMPTY_VALUE: Self::Value = EMPTY_WORD; const EMPTY_VALUE: Self::Value = EMPTY_WORD;
const EMPTY_ROOT: RpoDigest = *EmptySubtreeRoots::entry(DEPTH, 0);
fn root(&self) -> RpoDigest { fn root(&self) -> RpoDigest {
self.root self.root

+ 17
- 0
src/merkle/smt/simple/tests.rs

@ -444,6 +444,23 @@ fn test_simplesmt_set_subtree_entire_tree() {
assert_eq!(tree.root(), *EmptySubtreeRoots::entry(DEPTH, 0)); assert_eq!(tree.root(), *EmptySubtreeRoots::entry(DEPTH, 0));
} }
/// Tests that `EMPTY_ROOT` constant generated in the `SimpleSmt` equals to the root of the empty
/// tree of depth 64
#[test]
fn test_simplesmt_check_empty_root_constant() {
// get the root of the empty tree of depth 64
let empty_root_64_depth = EmptySubtreeRoots::empty_hashes(64)[0];
assert_eq!(empty_root_64_depth, SimpleSmt::<64>::EMPTY_ROOT);
// get the root of the empty tree of depth 32
let empty_root_32_depth = EmptySubtreeRoots::empty_hashes(32)[0];
assert_eq!(empty_root_32_depth, SimpleSmt::<32>::EMPTY_ROOT);
// get the root of the empty tree of depth 0
let empty_root_1_depth = EmptySubtreeRoots::empty_hashes(1)[0];
assert_eq!(empty_root_1_depth, SimpleSmt::<1>::EMPTY_ROOT);
}
// HELPER FUNCTIONS // HELPER FUNCTIONS
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------

Loading…
Cancel
Save