shardtree: Move error types into module
This commit is contained in:
parent
2a667f5009
commit
1bd0a7c941
|
@ -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},
|
||||
Checkpoint, IncompleteAt, LocatedPrunableTree, LocatedTree, Node, RetentionFlags, ShardStore,
|
||||
ShardTree, Tree,
|
||||
};
|
||||
|
||||
impl<
|
||||
|
|
|
@ -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: fmt::Debug + fmt::Display + 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 {}
|
|
@ -1,4 +1,4 @@
|
|||
use core::fmt::{self, Debug, Display};
|
||||
use core::fmt::Debug;
|
||||
use either::Either;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::sync::Arc;
|
||||
|
@ -8,6 +8,8 @@ use incrementalmerkletree::{
|
|||
frontier::NonEmptyFrontier, Address, Hashable, Level, MerklePath, Position, Retention,
|
||||
};
|
||||
|
||||
use self::error::{InsertionError, QueryError, ShardTreeError};
|
||||
|
||||
mod batch;
|
||||
pub use self::batch::BatchInsertionResult;
|
||||
|
||||
|
@ -15,9 +17,9 @@ mod tree;
|
|||
pub use self::tree::{LocatedTree, Node, Tree};
|
||||
|
||||
mod prunable;
|
||||
pub use self::prunable::{
|
||||
IncompleteAt, InsertionError, LocatedPrunableTree, PrunableTree, QueryError, RetentionFlags,
|
||||
};
|
||||
pub use self::prunable::{IncompleteAt, LocatedPrunableTree, PrunableTree, RetentionFlags};
|
||||
|
||||
pub mod error;
|
||||
|
||||
pub mod caching;
|
||||
pub mod memory;
|
||||
|
@ -304,53 +306,6 @@ pub struct ShardTree<S: ShardStore, const DEPTH: u8, const SHARD_HEIGHT: u8> {
|
|||
max_checkpoints: usize,
|
||||
}
|
||||
|
||||
#[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) => Display::fmt(&q, f),
|
||||
ShardTreeError::Insert(i) => Display::fmt(&i, 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: Debug + std::fmt::Display + std::error::Error + 'static,
|
||||
{
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match &self {
|
||||
ShardTreeError::Storage(e) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
H: Hashable + Clone + PartialEq,
|
||||
C: Clone + Debug + Ord,
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::fmt;
|
||||
use std::ops::Range;
|
||||
use std::sync::Arc;
|
||||
|
||||
use bitflags::bitflags;
|
||||
|
@ -9,6 +7,7 @@ use incrementalmerkletree::{
|
|||
};
|
||||
use tracing::trace;
|
||||
|
||||
use crate::error::{InsertionError, QueryError};
|
||||
use crate::{LocatedTree, Node, Tree};
|
||||
|
||||
bitflags! {
|
||||
|
@ -325,98 +324,6 @@ pub struct IncompleteAt {
|
|||
pub required_for_witness: bool,
|
||||
}
|
||||
|
||||
/// 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 {}
|
||||
|
||||
/// Operations on [`LocatedTree`]s that are annotated with Merkle hashes.
|
||||
impl<H: Hashable + Clone + PartialEq> LocatedPrunableTree<H> {
|
||||
/// Computes the root hash of this tree, truncated to the given position.
|
||||
|
@ -991,10 +898,13 @@ mod tests {
|
|||
|
||||
use incrementalmerkletree::{Address, Level, Position};
|
||||
|
||||
use super::{LocatedPrunableTree, PrunableTree, QueryError, RetentionFlags};
|
||||
use crate::tree::{
|
||||
tests::{leaf, nil, parent},
|
||||
LocatedTree,
|
||||
use super::{LocatedPrunableTree, PrunableTree, RetentionFlags};
|
||||
use crate::{
|
||||
error::QueryError,
|
||||
tree::{
|
||||
tests::{leaf, nil, parent},
|
||||
LocatedTree,
|
||||
},
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue