use core::fmt;
use crate::node_label::NodeLabel;
use crate::Direction;
#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Debug)]
pub enum AkdError {
TreeNode(TreeNodeError),
Directory(DirectoryError),
AzksErr(AzksError),
Vrf(akd_core::ecvrf::VrfError),
Storage(StorageError),
AuditErr(AuditorError),
Parallelism(ParallelismError),
TestErr(String),
}
impl std::error::Error for AkdError {}
impl From<TreeNodeError> for AkdError {
fn from(error: TreeNodeError) -> Self {
Self::TreeNode(error)
}
}
impl From<StorageError> for AkdError {
fn from(error: StorageError) -> Self {
Self::Storage(error)
}
}
impl From<DirectoryError> for AkdError {
fn from(error: DirectoryError) -> Self {
Self::Directory(error)
}
}
impl From<akd_core::ecvrf::VrfError> for AkdError {
fn from(error: akd_core::ecvrf::VrfError) -> Self {
Self::Vrf(error)
}
}
impl From<AzksError> for AkdError {
fn from(error: AzksError) -> Self {
Self::AzksErr(error)
}
}
impl From<AuditorError> for AkdError {
fn from(error: AuditorError) -> Self {
Self::AuditErr(error)
}
}
impl From<ParallelismError> for AkdError {
fn from(error: ParallelismError) -> Self {
Self::Parallelism(error)
}
}
impl From<akd_core::verify::VerificationError> for AkdError {
fn from(err: akd_core::verify::VerificationError) -> Self {
Self::Directory(err.into())
}
}
impl std::fmt::Display for AkdError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
AkdError::TreeNode(err) => {
writeln!(f, "AKD Tree Node Error: {err}")
}
AkdError::Directory(err) => {
writeln!(f, "AKD Directory Error: {err}")
}
AkdError::AzksErr(err) => {
writeln!(f, "AKD AZKS Error: {err}")
}
AkdError::Vrf(err) => {
writeln!(f, "AKD VRF Error: {err}")
}
AkdError::Storage(err) => {
writeln!(f, "AKD Storage Error: {err}")
}
AkdError::AuditErr(err) => {
writeln!(f, "AKD Auditor Error {err}")
}
AkdError::Parallelism(err) => {
writeln!(f, "AKD Parallelism Error: {err}")
}
AkdError::TestErr(err) => {
writeln!(f, "{err}")
}
}
}
}
#[derive(Debug, Eq, PartialEq)]
pub enum TreeNodeError {
InvalidDirection(Direction),
NoDirection(NodeLabel, Option<NodeLabel>),
NoChildAtEpoch(u64, Direction),
ParentNextEpochInvalid(u64),
HashUpdateOrderInconsistent,
NonexistentAtEpoch(NodeLabel, u64),
NoStateAtEpoch(NodeLabel, u64),
DigestDeserializationFailed(String),
}
impl std::error::Error for TreeNodeError {}
impl fmt::Display for TreeNodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidDirection(dir) => {
write!(
f,
"AKD is based on a binary tree. No child with a given direction: {dir:?}"
)
}
Self::NoDirection(node_label, child_label) => {
let mut to_print = format!("no direction provided for the node {node_label:?}");
if let Some(child_label) = child_label {
let child_str = format!(" and child {child_label:?}");
to_print.push_str(&child_str);
}
write!(f, "{to_print}")
}
Self::NoChildAtEpoch(epoch, direction) => {
write!(f, "no node in direction {direction:?} at epoch {epoch}")
}
Self::ParentNextEpochInvalid(epoch) => {
write!(f, "Next epoch of parent is invalid, epoch = {epoch}")
}
Self::HashUpdateOrderInconsistent => {
write!(
f,
"Hash update in parent only allowed after node is inserted"
)
}
Self::NonexistentAtEpoch(label, epoch) => {
write!(
f,
"This node, labelled {label:?}, did not exist at epoch {epoch:?}."
)
}
Self::NoStateAtEpoch(label, epoch) => {
write!(
f,
"This node, labelled {label:?}, did not exist at epoch {epoch:?}."
)
}
Self::DigestDeserializationFailed(inner_error) => {
write!(f, "Encountered a serialization error {inner_error}")
}
}
}
}
#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Debug)]
pub enum AzksError {
VerifyMembershipProof(String),
VerifyAppendOnlyProof,
NoEpochGiven,
}
impl std::error::Error for AzksError {}
impl fmt::Display for AzksError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::VerifyMembershipProof(error_string) => {
write!(f, "{error_string}")
}
Self::VerifyAppendOnlyProof => {
write!(f, "Append only proof did not verify!")
}
Self::NoEpochGiven => {
write!(f, "An epoch was required but not supplied")
}
}
}
}
#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Debug)]
pub enum DirectoryError {
Verification(akd_core::verify::VerificationError),
InvalidEpoch(String),
ReadOnlyDirectory(String),
Publish(String),
}
impl std::error::Error for DirectoryError {}
impl fmt::Display for DirectoryError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Verification(err) => {
write!(f, "Verification failure {err}")
}
Self::InvalidEpoch(err_string) => {
write!(f, "Invalid epoch {err_string}")
}
Self::ReadOnlyDirectory(inner_message) => {
write!(f, "Directory in read-only mode: {inner_message}")
}
Self::Publish(inner_message) => {
write!(f, "Directory publish error: {inner_message}")
}
}
}
}
impl From<akd_core::verify::VerificationError> for DirectoryError {
fn from(err: akd_core::verify::VerificationError) -> Self {
Self::Verification(err)
}
}
#[cfg_attr(any(test, feature = "public_tests"), derive(PartialEq, Eq))]
#[derive(Debug)]
pub enum StorageError {
NotFound(String),
Transaction(String),
Connection(String),
Other(String),
}
impl std::error::Error for StorageError {}
impl fmt::Display for StorageError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
StorageError::Connection(inner) => {
write!(f, "Storage connection: {inner}")
}
StorageError::Transaction(inner) => {
write!(f, "Transaction: {inner}")
}
StorageError::NotFound(inner) => {
write!(f, "Data not found: {inner}")
}
StorageError::Other(inner) => {
write!(f, "Other storage error: {inner}")
}
}
}
}
#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Debug)]
pub enum AuditorError {
VerifyAuditProof(String),
}
impl std::error::Error for AuditorError {}
impl fmt::Display for AuditorError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::VerifyAuditProof(err_string) => {
write!(f, "Failed to verify audit {err_string}")
}
}
}
}
#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Debug)]
pub enum ParallelismError {
JoinErr(String),
}
impl std::error::Error for ParallelismError {}
impl fmt::Display for ParallelismError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::JoinErr(err_string) => {
write!(f, "Failed to join tokio task {err_string}")
}
}
}
}