Skip to content

Commit

Permalink
better internal error fix
Browse files Browse the repository at this point in the history
  • Loading branch information
QuantumExplorer committed Jun 24, 2024
1 parent 0b32606 commit 8664b72
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 2 deletions.
4 changes: 2 additions & 2 deletions grovedb/src/element/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ use grovedb_path::SubtreePath;
#[cfg(feature = "full")]
use grovedb_storage::{rocksdb_storage::RocksDbStorage, RawIterator, StorageContext};

use crate::query_result_type::Path;
#[cfg(feature = "full")]
use crate::{
element::helpers::raw_decode,
Expand All @@ -56,6 +55,7 @@ use crate::{
util::{merk_optional_tx, storage_context_optional_tx},
Error, PathQuery, TransactionArg,
};
use crate::{query_result_type::Path, util::merk_optional_tx_internal_error};
#[cfg(any(feature = "full", feature = "verify"))]
use crate::{Element, SizedQuery};

Expand Down Expand Up @@ -563,7 +563,7 @@ impl Element {
if !item.is_range() {
// this is a query on a key
if let QueryItem::Key(key) = item {
let element_res = merk_optional_tx!(
let element_res = merk_optional_tx_internal_error!(
&mut cost,
storage,
subtree_path,
Expand Down
183 changes: 183 additions & 0 deletions grovedb/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,117 @@ macro_rules! storage_context_with_parent_optional_tx {
};
}

/// Macro to execute same piece of code on different storage contexts
/// (transactional or not) using path argument.
macro_rules! storage_context_with_parent_optional_tx_internal_error {
(
&mut $cost:ident,
$db:expr,
$path:expr,
$batch:expr,
$transaction:ident,
$storage:ident,
$root_key:ident,
$is_sum_tree:ident,
{ $($body:tt)* }
) => {
{
use ::grovedb_storage::Storage;
if let Some(tx) = $transaction {
let $storage = $db
.get_transactional_storage_context($path.clone(), $batch, tx)
.unwrap_add_cost(&mut $cost);
if let Some((parent_path, parent_key)) = $path.derive_parent() {
let parent_storage = $db
.get_transactional_storage_context(parent_path, $batch, tx)
.unwrap_add_cost(&mut $cost);
let result = Element::get_from_storage(&parent_storage, parent_key)
.map_err(|e| {
Error::PathParentLayerNotFound(
format!(
"could not get key for parent of subtree optional on tx: {}",
e
)
)
}).unwrap_add_cost(&mut $cost);
match result {
Ok(element) => {
match element {
Element::Tree(root_key, _) => {
let $root_key = root_key;
let $is_sum_tree = false;
$($body)*
}
Element::SumTree(root_key, ..) => {
let $root_key = root_key;
let $is_sum_tree = true;
$($body)*
}
_ => {
return Err(Error::CorruptedData(
"parent is not a tree"
.to_owned(),
)).wrap_with_cost($cost);
}
}
},
Err(e) => Err(e),
}
} else {
return Err(Error::CorruptedData(
"path is empty".to_owned(),
)).wrap_with_cost($cost);
}
} else {
let $storage = $db
.get_storage_context($path.clone(), $batch).unwrap_add_cost(&mut $cost);
if let Some((parent_path, parent_key)) = $path.derive_parent() {
let parent_storage = $db.get_storage_context(
parent_path,
$batch
).unwrap_add_cost(&mut $cost);
let result = Element::get_from_storage(&parent_storage, parent_key)
.map_err(|e| {
Error::PathParentLayerNotFound(
format!(
"could not get key for parent of subtree optional no tx: {}",
e
)
)
}).unwrap_add_cost(&mut $cost);
match result {
Ok(element) => {
match element {
Element::Tree(root_key, _) => {
let $root_key = root_key;
let $is_sum_tree = false;
$($body)*
}
Element::SumTree(root_key, ..) => {
let $root_key = root_key;
let $is_sum_tree = true;
$($body)*
}
_ => {
return Err(Error::CorruptedData(
"parent is not a tree"
.to_owned(),
)).wrap_with_cost($cost);
}
}
},
Err(e) => Err(e),
}
} else {
return Err(Error::CorruptedData(
"path is empty".to_owned(),
)).wrap_with_cost($cost);
}
}
}
};
}

/// Macro to execute same piece of code on different storage contexts with
/// empty prefix.
macro_rules! meta_storage_context_optional_tx {
Expand Down Expand Up @@ -245,6 +356,76 @@ macro_rules! merk_optional_tx {
};
}

/// Macro to execute same piece of code on Merk with varying storage
/// contexts.
macro_rules! merk_optional_tx_internal_error {
(
&mut $cost:ident,
$db:expr,
$path:expr,
$batch:expr,
$transaction:ident,
$subtree:ident,
{ $($body:tt)* }
) => {
if $path.is_root() {
use crate::util::storage_context_optional_tx;
storage_context_optional_tx!(
$db,
::grovedb_path::SubtreePath::empty(),
$batch,
$transaction,
storage,
{
let $subtree = cost_return_on_error!(
&mut $cost,
::grovedb_merk::Merk::open_base(
storage.unwrap_add_cost(&mut $cost),
false,
Some(&Element::value_defined_cost_for_serialized_value)
).map(|merk_res|
merk_res
.map_err(|_| crate::Error::CorruptedData(
"cannot open a subtree".to_owned()
))
)
);
$($body)*
})
} else {
use crate::util::storage_context_with_parent_optional_tx_internal_error;
storage_context_with_parent_optional_tx_internal_error!(
&mut $cost,
$db,
$path,
$batch,
$transaction,
storage,
root_key,
is_sum_tree,
{
#[allow(unused_mut)]
let mut $subtree = cost_return_on_error!(
&mut $cost,
::grovedb_merk::Merk::open_layered_with_root_key(
storage,
root_key,
is_sum_tree,
Some(&Element::value_defined_cost_for_serialized_value),
).map(|merk_res|
merk_res
.map_err(|_| crate::Error::CorruptedData(
"cannot open a subtree".to_owned()
))
)
);
$($body)*
}
)
}
};
}

/// Macro to execute same piece of code on Merk with varying storage
/// contexts.
macro_rules! merk_optional_tx_path_not_empty {
Expand Down Expand Up @@ -331,8 +512,10 @@ macro_rules! root_merk_optional_tx {
}

pub(crate) use merk_optional_tx;
pub(crate) use merk_optional_tx_internal_error;
pub(crate) use merk_optional_tx_path_not_empty;
pub(crate) use meta_storage_context_optional_tx;
pub(crate) use root_merk_optional_tx;
pub(crate) use storage_context_optional_tx;
pub(crate) use storage_context_with_parent_optional_tx;
pub(crate) use storage_context_with_parent_optional_tx_internal_error;

0 comments on commit 8664b72

Please sign in to comment.