-
Notifications
You must be signed in to change notification settings - Fork 78
feat(SmtForest) Skeleton out the new forest #767
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| //! This file contains the [`Backend`] trait for the [`LargeSmtForest`] implementation and the | ||
| //! supporting types it needs. | ||
|
|
||
| use alloc::{boxed::Box, vec::Vec}; | ||
| use core::fmt::Debug; | ||
|
|
||
| use thiserror::Error; | ||
|
|
||
| use crate::{ | ||
| Word, | ||
| merkle::{ | ||
| MerkleError, | ||
| smt::{ | ||
| SmtProof, | ||
| full::SMT_DEPTH, | ||
| large_forest::{ | ||
| history::VersionId, | ||
| operation::{SmtForestUpdateBatch, SmtUpdateBatch}, | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
| // TYPE ALIASES | ||
| // ================================================================================================ | ||
|
|
||
| /// The mutation set used by the forest backends. | ||
| /// | ||
| /// At the moment this is used for _reverse_ mutations that "undo" the changes made to the tree(s), | ||
| /// but may be harmonised with [`SmtUpdateBatch`] in the future. For more information on its use for | ||
| /// reverse mutations, see [`crate::merkle::smt::SparseMerkleTree::apply_mutations_with_reversion`]. | ||
| pub type MutationSet = crate::merkle::smt::MutationSet<SMT_DEPTH, Word, Word>; | ||
|
|
||
| // BACKEND | ||
| // ================================================================================================ | ||
|
|
||
| /// The backing storage for the SMT forest, providing the necessary high-level methods for | ||
| /// performing operations on the full trees that make up the forest, while allowing the forest | ||
| /// itself to be storage agnostic. | ||
| /// | ||
| /// # Backend Data Storage | ||
| /// | ||
| /// Having a generic [`Backend`] provides no guarantees to the user about how it stores data and | ||
| /// what patterns are used for data access under the hood. It is, however, guaranteed to store | ||
| /// _only_ the data necessary to describe the latest state of each tree in the forest. | ||
| pub trait Backend | ||
| where | ||
| Self: Debug, | ||
| { | ||
| // QUERIES | ||
| // ============================================================================================ | ||
|
|
||
| /// Returns an opening for the specified `key` in the SMT with the specified `root`. | ||
| fn open(&self, root: Word, key: Word) -> Result<SmtProof>; | ||
|
|
||
| /// Returns the value associated with the provided `key` in the SMT with the provided `root`, or | ||
| /// [`None`] if no such value exists. | ||
| fn get(&self, root: Word, key: Word) -> Result<Option<Word>>; | ||
|
|
||
| /// Returns the version of the tree with the provided `root`. | ||
| fn version(&self, root: Word) -> Result<VersionId>; | ||
|
|
||
| /// Returns an iterator over all the tree roots and versions that the backend knows about. | ||
| /// | ||
| /// The iteration order is unspecified. | ||
| fn versions(&self) -> Result<impl Iterator<Item = (Word, VersionId)>>; | ||
|
|
||
| // SINGLE-TREE MODIFIERS | ||
| // ============================================================================================ | ||
|
|
||
| /// Performs the provided `updates` on the tree with the provided `root`, returning the mutation | ||
| /// set that will revert the changes made to the tree. | ||
| /// | ||
| /// Implementations must guarantee the following behavior, with non-conforming implementations | ||
| /// considered to be a bug: | ||
| /// | ||
| /// - At most one new root must be added to the forest for the entire batch. | ||
| /// - If applying the provided `updates` results in no changes to the tree, no new tree must be | ||
| /// allocated. | ||
| fn update_tree( | ||
| &mut self, | ||
| root: Word, | ||
| new_version: VersionId, | ||
| updates: SmtUpdateBatch, | ||
| ) -> Result<MutationSet>; | ||
|
|
||
| // MULTI-TREE MODIFIERS | ||
| // ============================================================================================ | ||
|
|
||
| /// Performs the provided `updates` on the forest, setting all new tree states to have the | ||
| /// provided `new_version` and returning a vector of the mutation sets that reverse the changes | ||
| /// to each changed tree. | ||
| /// | ||
| /// Implementations must guarantee the following behaviour, with non-conforming implementations | ||
| /// considered to be a bug: | ||
| /// | ||
| /// - At most one new root must be added to the forest for each target root in the provided | ||
| /// `updates`. | ||
| /// - If applying the provided `updates` results in no changes to a given lineage of trees in | ||
| /// the forest, then no new tree must be allocated in that lineage. | ||
| fn update_forest( | ||
| &mut self, | ||
| new_version: VersionId, | ||
| updates: SmtForestUpdateBatch, | ||
| ) -> Result<Vec<MutationSet>>; | ||
| } | ||
|
|
||
| // BACKEND ERROR | ||
| // ================================================================================================ | ||
|
|
||
| /// The error type for use within Backends. | ||
| #[derive(Debug, Error)] | ||
| pub enum BackendError { | ||
| /// Raised when there is an error with the merkle tree semantics within the backend. | ||
| #[error(transparent)] | ||
| Merkle(#[from] MerkleError), | ||
|
|
||
| /// Raised for arbitrary other errors within the backend. | ||
| #[error(transparent)] | ||
| Other(#[from] Box<dyn core::error::Error + Sync + Send>), | ||
| } | ||
|
|
||
| /// The result type for use with backends. | ||
| pub type Result<T> = core::result::Result<T, BackendError>; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,21 +1,51 @@ | ||
| //! This module contains the error types and helpers for working with errors from the large SMT | ||
| //! forest. | ||
|
|
||
| use alloc::boxed::Box; | ||
|
|
||
| use thiserror::Error; | ||
|
|
||
| use crate::merkle::{MerkleError, smt::large_forest::history::error::HistoryError}; | ||
| use crate::{ | ||
| Word, | ||
| merkle::{ | ||
| MerkleError, | ||
| smt::large_forest::{backend::BackendError, history::error::HistoryError}, | ||
| }, | ||
| }; | ||
|
|
||
| // LARGE SMT FOREST ERROR | ||
| // ================================================================================================ | ||
|
|
||
| /// The errors returned by operations on the large SMT forest. | ||
| /// | ||
| /// This type primarily serves to wrap more specific error types from various subsystems into a | ||
| /// generic interface type. | ||
| /// The type of errors returned by operations on the large SMT forest. | ||
| #[derive(Debug, Error)] | ||
| pub enum LargeSmtForestError { | ||
| /// Errors in the history subsystem of the forest. | ||
| #[error(transparent)] | ||
| HistoryError(#[from] HistoryError), | ||
|
|
||
| /// Raised when an attempt is made to modify a frozen tree. | ||
| #[error("Attempted to modify non-current tree with root {0}")] | ||
| InvalidModification(Word), | ||
|
|
||
| /// Errors with the merkle tree operations of the forest. | ||
| #[error(transparent)] | ||
| MerkleError(#[from] MerkleError), | ||
|
|
||
| /// Raised for arbitrary other errors. | ||
| #[error(transparent)] | ||
| Other(#[from] Box<dyn core::error::Error + Sync + Send>), | ||
| } | ||
|
|
||
| /// We want to forward backend errors specifically when we can, so we manually implement the | ||
| /// conversion. | ||
| impl From<BackendError> for LargeSmtForestError { | ||
| fn from(value: BackendError) -> Self { | ||
| match value { | ||
| BackendError::Merkle(e) => LargeSmtForestError::from(e), | ||
| BackendError::Other(e) => LargeSmtForestError::from(e), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| pub mod history {} | ||
| /// The result type for use within the large SMT forest portion of the library. | ||
| pub type Result<T> = core::result::Result<T, LargeSmtForestError>; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.