Add methods to Smt
necessary for VM tests (#264)
* Smt::inner_nodes * Add conversion Smt -> MerkleStore * add docstring to `Smt` * add to docstring * fmt * add `leaves()` method to `Smt` * add `kv_pairs` functions * rewrite `into_elements()` in terms of `into_kv_pairs()` * change docstring
This commit is contained in:
parent
d59ffe274a
commit
1cdd3dbbfa
2 changed files with 53 additions and 4 deletions
|
@ -3,7 +3,7 @@ use core::cmp::Ordering;
|
||||||
use winter_math::StarkField;
|
use winter_math::StarkField;
|
||||||
|
|
||||||
use crate::hash::rpo::Rpo256;
|
use crate::hash::rpo::Rpo256;
|
||||||
use crate::merkle::EmptySubtreeRoots;
|
use crate::merkle::{EmptySubtreeRoots, InnerNodeInfo};
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
collections::{BTreeMap, BTreeSet, Vec},
|
collections::{BTreeMap, BTreeSet, Vec},
|
||||||
vec,
|
vec,
|
||||||
|
@ -25,6 +25,15 @@ pub const SMT_DEPTH: u8 = 64;
|
||||||
// SMT
|
// SMT
|
||||||
// ================================================================================================
|
// ================================================================================================
|
||||||
|
|
||||||
|
/// Sparse Merkle tree mapping 256-bit keys to 256-bit values. Both keys and values are represented
|
||||||
|
/// by 4 field elements.
|
||||||
|
///
|
||||||
|
/// All leaves sit at depth 64. The most significant element of the key is used to identify the leaf to
|
||||||
|
/// which the key maps.
|
||||||
|
///
|
||||||
|
/// A leaf is either empty, or holds one or more key-value pairs. An empty leaf hashes to the empty
|
||||||
|
/// word. Otherwise, a leaf hashes to the hash of its key-value pairs, ordered by key first, value
|
||||||
|
/// second.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub struct Smt {
|
pub struct Smt {
|
||||||
|
@ -111,6 +120,25 @@ impl Smt {
|
||||||
<Self as SparseMerkleTree<SMT_DEPTH>>::open(self, key)
|
<Self as SparseMerkleTree<SMT_DEPTH>>::open(self, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ITERATORS
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Returns an iterator over the leaves of this [Smt].
|
||||||
|
pub fn leaves(&self) -> impl Iterator<Item = (LeafIndex<SMT_DEPTH>, &SmtLeaf)> {
|
||||||
|
self.leaves
|
||||||
|
.iter()
|
||||||
|
.map(|(leaf_index, leaf)| (LeafIndex::new_max_depth(*leaf_index), leaf))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over the inner nodes of this [Smt].
|
||||||
|
pub fn inner_nodes(&self) -> impl Iterator<Item = InnerNodeInfo> + '_ {
|
||||||
|
self.inner_nodes.values().map(|e| InnerNodeInfo {
|
||||||
|
value: e.hash(),
|
||||||
|
left: e.left,
|
||||||
|
right: e.right,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// STATE MUTATORS
|
// STATE MUTATORS
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -242,10 +270,24 @@ impl SmtLeaf {
|
||||||
|
|
||||||
/// Converts a leaf to a list of field elements
|
/// Converts a leaf to a list of field elements
|
||||||
pub fn into_elements(self) -> Vec<Felt> {
|
pub fn into_elements(self) -> Vec<Felt> {
|
||||||
|
self.into_kv_pairs().into_iter().flat_map(kv_to_elements).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the key-value pairs in the leaf
|
||||||
|
pub fn kv_pairs(&self) -> Vec<&(RpoDigest, Word)> {
|
||||||
match self {
|
match self {
|
||||||
SmtLeaf::Empty => Vec::new(),
|
SmtLeaf::Empty => Vec::new(),
|
||||||
SmtLeaf::Single(kv_pair) => kv_to_elements(kv_pair).collect(),
|
SmtLeaf::Single(kv_pair) => vec![kv_pair],
|
||||||
SmtLeaf::Multiple(kv_pairs) => kv_pairs.into_iter().flat_map(kv_to_elements).collect(),
|
SmtLeaf::Multiple(kv_pairs) => kv_pairs.iter().collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a leaf the key-value pairs in the leaf
|
||||||
|
pub fn into_kv_pairs(self) -> Vec<(RpoDigest, Word)> {
|
||||||
|
match self {
|
||||||
|
SmtLeaf::Empty => Vec::new(),
|
||||||
|
SmtLeaf::Single(kv_pair) => vec![kv_pair],
|
||||||
|
SmtLeaf::Multiple(kv_pairs) => kv_pairs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::{
|
use super::{
|
||||||
mmr::Mmr, BTreeMap, EmptySubtreeRoots, InnerNodeInfo, KvMap, MerkleError, MerklePath,
|
mmr::Mmr, BTreeMap, EmptySubtreeRoots, InnerNodeInfo, KvMap, MerkleError, MerklePath,
|
||||||
MerkleTree, NodeIndex, PartialMerkleTree, RecordingMap, RootPath, Rpo256, RpoDigest, SimpleSmt,
|
MerkleTree, NodeIndex, PartialMerkleTree, RecordingMap, RootPath, Rpo256, RpoDigest, SimpleSmt,
|
||||||
TieredSmt, ValuePath, Vec,
|
Smt, TieredSmt, ValuePath, Vec,
|
||||||
};
|
};
|
||||||
use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
|
use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
|
||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
|
@ -497,6 +497,13 @@ impl<T: KvMap<RpoDigest, StoreNode>, const DEPTH: u8> From<&SimpleSmt<DEPTH>> fo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: KvMap<RpoDigest, StoreNode>> From<&Smt> for MerkleStore<T> {
|
||||||
|
fn from(value: &Smt) -> Self {
|
||||||
|
let nodes = combine_nodes_with_empty_hashes(value.inner_nodes()).collect();
|
||||||
|
Self { nodes }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: KvMap<RpoDigest, StoreNode>> From<&Mmr> for MerkleStore<T> {
|
impl<T: KvMap<RpoDigest, StoreNode>> From<&Mmr> for MerkleStore<T> {
|
||||||
fn from(value: &Mmr) -> Self {
|
fn from(value: &Mmr) -> Self {
|
||||||
let nodes = combine_nodes_with_empty_hashes(value.inner_nodes()).collect();
|
let nodes = combine_nodes_with_empty_hashes(value.inner_nodes()).collect();
|
||||||
|
|
Loading…
Add table
Reference in a new issue