diff --git a/CHANGELOG.md b/CHANGELOG.md index e4cd462010..fa40533c97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ #### Changes - `FastProcessor` `restore_call_state()` and `restore_context()` now return `OperationError::Internal` instead of panicking on empty stacks ([#3371](https://github.com/0xMiden/miden-vm/pull/3371), fixes [#3296](https://github.com/0xMiden/miden-vm/issues/3296)). +- Opened the `LargeSmtForest` backend API for external implementations: made `LineageMutation::new` and `AppliedLineageMutation::new` public and added `LineageId::as_bytes` and `MutationSet::from_parts`. - [BREAKING] Renamed module and kernel metadata APIs from `ModuleInfo`/`Kernel` to `ModuleDescriptor`/`KernelDescriptor`, including matching module descriptor method names ([#3356](https://github.com/0xMiden/miden-vm/pull/3356)). - Aligned workspace crate versions at `0.28.0`, except `midenc-hir-type`, so VM and crypto crates release as one version line. - Imported the Miden crypto crates, benches, fuzz targets, and Wycheproof tests into this workspace ([#3366](https://github.com/0xMiden/miden-vm/pull/3366)). diff --git a/crates/crypto/src/merkle/smt/large_forest/root.rs b/crates/crypto/src/merkle/smt/large_forest/root.rs index b928859201..e52e510ef3 100644 --- a/crates/crypto/src/merkle/smt/large_forest/root.rs +++ b/crates/crypto/src/merkle/smt/large_forest/root.rs @@ -37,6 +37,14 @@ impl LineageId { pub fn new(bytes: [u8; 32]) -> Self { Self(bytes) } + + /// Returns the raw bytes of the lineage ID. + /// + /// This is primarily useful for [`Backend`](super::backend::Backend) implementations that + /// need to persist lineage identifiers. + pub fn as_bytes(&self) -> &[u8; 32] { + &self.0 + } } impl core::fmt::Display for LineageId { diff --git a/crates/crypto/src/merkle/smt/large_forest/utils.rs b/crates/crypto/src/merkle/smt/large_forest/utils.rs index 130a447619..4d33761ea3 100644 --- a/crates/crypto/src/merkle/smt/large_forest/utils.rs +++ b/crates/crypto/src/merkle/smt/large_forest/utils.rs @@ -108,9 +108,10 @@ pub struct LineageMutation { impl LineageMutation { /// Constructs a lineage mutation. /// - /// This constructor is crate-private because callers must not be able to fabricate mutation - /// metadata that is inconsistent with the backend-prepared data in an [`SmtForestMutationSet`]. - pub(crate) fn new( + /// This is intended for [`Backend`] implementations returning computed mutations. The + /// metadata must stay consistent with the backend-prepared data in the corresponding + /// [`SmtForestMutationSet`]. + pub fn new( lineage: LineageId, old_version: Option, new_version: VersionId, @@ -207,10 +208,10 @@ pub struct AppliedLineageMutation { impl AppliedLineageMutation { /// Constructs an applied lineage mutation. /// - /// This constructor is crate-private because backend implementations must keep the returned - /// history payload consistent with the prepared mutation data they just applied. + /// [`Backend`] implementations must keep the returned history payload consistent with the + /// prepared mutation data they just applied. #[allow(clippy::too_many_arguments)] - pub(crate) fn new( + pub fn new( lineage: LineageId, old_version: Option, new_version: VersionId, diff --git a/crates/crypto/src/merkle/smt/mod.rs b/crates/crypto/src/merkle/smt/mod.rs index 475f1c90fc..05616caa76 100644 --- a/crates/crypto/src/merkle/smt/mod.rs +++ b/crates/crypto/src/merkle/smt/mod.rs @@ -734,6 +734,29 @@ impl MutationSet { && self.new_pairs.is_empty() && self.old_root == self.new_root } + + /// Creates a new mutation set from pre-computed components. + /// + /// This constructor performs no validation. The caller must ensure the components are + /// internally consistent, meaning that applying `node_mutations` and `new_pairs` to a tree + /// whose root is `old_root` yields a tree whose root is `new_root`. Intended for storage + /// backends that compute mutations from persisted tree data instead of an in-memory tree. + pub fn from_parts( + old_root: Word, + node_mutations: impl IntoIterator, + new_pairs: impl IntoIterator, + new_root: Word, + ) -> Self + where + K: Ord, + { + Self { + old_root, + node_mutations: node_mutations.into_iter().collect(), + new_pairs: new_pairs.into_iter().collect(), + new_root, + } + } } // SERIALIZATION