Skip to content
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

Cleanups ahead of publishing shardtree crate #89

Merged
merged 3 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions shardtree/src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ use incrementalmerkletree::{Address, Hashable, Level, Position, Retention};
use tracing::trace;

use crate::{
Checkpoint, IncompleteAt, InsertionError, LocatedPrunableTree, LocatedTree, Node,
RetentionFlags, ShardStore, ShardTree, ShardTreeError, Tree,
error::{InsertionError, ShardTreeError},
store::{Checkpoint, ShardStore},
IncompleteAt, LocatedPrunableTree, LocatedTree, Node, RetentionFlags, ShardTree, Tree,
};

impl<
Expand Down Expand Up @@ -388,7 +389,7 @@ mod tests {

use super::{LocatedPrunableTree, RetentionFlags};
use crate::{
memory::MemoryShardStore,
store::memory::MemoryShardStore,
tree::tests::{leaf, nil, parent},
BatchInsertionResult, ShardTree,
};
Expand Down
143 changes: 143 additions & 0 deletions shardtree/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
use std::fmt;
use std::ops::Range;

use incrementalmerkletree::{Address, Position};

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ShardTreeError<S> {
Query(QueryError),
Insert(InsertionError),
Storage(S),
}

impl<S> From<QueryError> for ShardTreeError<S> {
fn from(err: QueryError) -> Self {
ShardTreeError::Query(err)
}
}

impl<S> From<InsertionError> for ShardTreeError<S> {
fn from(err: InsertionError) -> Self {
ShardTreeError::Insert(err)
}
}

impl<S: fmt::Display> fmt::Display for ShardTreeError<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
ShardTreeError::Query(q) => q.fmt(f),
ShardTreeError::Insert(i) => i.fmt(f),
ShardTreeError::Storage(s) => {
write!(
f,
"An error occurred persisting or retrieving tree data: {}",
s
)
}
}
}
}

impl<SE> std::error::Error for ShardTreeError<SE>
where
SE: std::error::Error + 'static,
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match &self {
ShardTreeError::Storage(e) => Some(e),
_ => None,
}
}
}

/// An error prevented the insertion of values into the subtree.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum InsertionError {
/// The caller attempted to insert a subtree into a tree that does not contain
/// the subtree's root address.
NotContained(Address),
/// The start of the range of positions provided for insertion is not included
/// in the range of positions within this subtree.
OutOfRange(Position, Range<Position>),
/// An existing root hash conflicts with the root hash of a node being inserted.
Conflict(Address),
/// An out-of-order checkpoint was detected
///
/// Checkpoint identifiers must be in nondecreasing order relative to tree positions.
CheckpointOutOfOrder,
/// An append operation has exceeded the capacity of the tree.
TreeFull,
/// An input data structure had malformed data when attempting to insert a value
/// at the given address
InputMalformed(Address),
}

impl fmt::Display for InsertionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
InsertionError::NotContained(addr) => {
write!(f, "Tree does not contain a root at address {:?}", addr)
}
InsertionError::OutOfRange(p, r) => {
write!(
f,
"Attempted insertion point {:?} is not in range {:?}",
p, r
)
}
InsertionError::Conflict(addr) => write!(
f,
"Inserted root conflicts with existing root at address {:?}",
addr
),
InsertionError::CheckpointOutOfOrder => {
write!(f, "Cannot append out-of-order checkpoint identifier.")
}
InsertionError::TreeFull => write!(f, "Note commitment tree is full."),
InsertionError::InputMalformed(addr) => {
write!(f, "Input malformed for insertion at address {:?}", addr)
}
}
}
}

impl std::error::Error for InsertionError {}

/// Errors that may be returned in the process of querying a [`ShardTree`]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum QueryError {
/// The caller attempted to query the value at an address within a tree that does not contain
/// that address.
NotContained(Address),
/// A leaf required by a given checkpoint has been pruned, or is otherwise not accessible in
/// the tree.
CheckpointPruned,
/// It is not possible to compute a root for one or more subtrees because they contain
/// [`Node::Nil`] values at positions that cannot be replaced with default hashes.
TreeIncomplete(Vec<Address>),
}

impl fmt::Display for QueryError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
QueryError::NotContained(addr) => {
write!(f, "Tree does not contain a root at address {:?}", addr)
}
QueryError::CheckpointPruned => {
write!(
f,
"The leaf corresponding to the requested checkpoint is not present in the tree."
)
}
QueryError::TreeIncomplete(addrs) => {
write!(
f,
"Unable to compute root; missing values for nodes {:?}",
addrs
)
}
}
}
}

impl std::error::Error for QueryError {}
4 changes: 2 additions & 2 deletions shardtree/src/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::fmt;
use incrementalmerkletree::{witness::IncrementalWitness, Address, Hashable, Level, Retention};

use crate::{
InsertionError, LocatedPrunableTree, LocatedTree, PrunableTree, RetentionFlags, ShardStore,
ShardTree, ShardTreeError, Tree,
store::ShardStore, InsertionError, LocatedPrunableTree, LocatedTree, PrunableTree,
RetentionFlags, ShardTree, ShardTreeError, Tree,
};

impl<
Expand Down
Loading
Loading