pub trait Backend: BackendReader {
type Reader: BackendReader;
type PreparedMutations;
// Required methods
fn reader(&self) -> Result<Self::Reader, BackendError>;
fn compute_mutations(
&self,
new_version: u64,
updates: SmtForestUpdateBatch,
) -> Result<(Vec<LineageMutation>, Self::PreparedMutations), BackendError>;
fn apply_mutations(
&mut self,
mutations: Self::PreparedMutations,
) -> Result<Vec<AppliedLineageMutation>, BackendError>;
}Expand description
The full read-write interface for the SMT forest storage backend.
This trait extends BackendReader with mutation operations, allowing the forest to add new
lineages and update existing ones.
§Implementation Contract
Method-level doc comments describe invariants that cannot be encoded in the type system. Implementations are responsible for upholding them.
Required Associated Types§
Sourcetype Reader: BackendReader
type Reader: BackendReader
The read-only view type returned by Self::reader.
The returned type implements BackendReader but not Backend, providing a read-only
guarantee. Implementations may return either a point-in-time snapshot or a live view, but
the view must always reflect a consistent committed state (not partial writes). Holding the
reader must not block writes in any way.
Sourcetype PreparedMutations
type PreparedMutations
Backend-specific data prepared during mutation computation and consumed during application.
This type is intentionally opaque to forest users. Implementations should store enough information here to apply the already-computed mutations without repeating the expensive tree update computation.
The prepared value must represent only prospective changes. Computing it must not change the backend’s committed state. It may contain ordinary SMT mutation sets, storage-level updates, serialized values, or any other implementation-specific data needed to apply the mutation efficiently later.
Required Methods§
Sourcefn reader(&self) -> Result<Self::Reader, BackendError>
fn reader(&self) -> Result<Self::Reader, BackendError>
Returns a read-only view of this backend that observes its current state.
Sourcefn compute_mutations(
&self,
new_version: u64,
updates: SmtForestUpdateBatch,
) -> Result<(Vec<LineageMutation>, Self::PreparedMutations), BackendError>
fn compute_mutations( &self, new_version: u64, updates: SmtForestUpdateBatch, ) -> Result<(Vec<LineageMutation>, Self::PreparedMutations), BackendError>
Computes the backend data required to mutate lineages, without applying it.
§Expected Behavior
Implementations must guarantee the following behavior in addition to the global invariants:
- The backend’s committed state must not change.
- Each unknown lineage in
updatesis treated as an addition from the empty tree. - Each known lineage in
updatesis treated as an update to its latest tree. - Each lineage in
updatesmust produce at most oneLineageMutation. - No-op lineage updates must not allocate new backend tree versions when applied.
- The prepared mutations must be applicable atomically by
Self::apply_mutationswhere the backend supports atomic writes.
Sourcefn apply_mutations(
&mut self,
mutations: Self::PreparedMutations,
) -> Result<Vec<AppliedLineageMutation>, BackendError>
fn apply_mutations( &mut self, mutations: Self::PreparedMutations, ) -> Result<Vec<AppliedLineageMutation>, BackendError>
Applies previously-computed backend mutations.
This method consumes the opaque prepared data returned by one of the backend compute
methods. It commits the backend’s latest-tree state and returns the applied lineage data
needed by crate::merkle::smt::LargeSmtForest to update forest-level lineage metadata and
history.
§Expected Behavior
Implementations must guarantee the following behavior in addition to the global invariants:
- The prepared mutation data must still be applicable to the current backend state before any mutation is written. For updates, the current version and root must match the version/root captured during the compute phase. For additions, the lineage must still be absent.
- User-derived errors must leave the backend in a consistent committed state.
- If the prepared data contains multiple lineage updates, they should be committed atomically when the backend’s storage engine supports atomic batched writes.
- The method must not recompute Merkle mutations from the original user updates; that work belongs to the compute methods.
- On success, the returned
AppliedLineageMutationvalues must correspond to the applied prepared mutations in the same lineage set, including reverse mutations and old entry counts for update history.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".