From 9c08bc896c49f8c9a7699e2a51e2cda40d5aa1b9 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 10 Jul 2024 15:33:22 +0700 Subject: [PATCH] more work --- .../src/version/grovedb_versions.rs | 18 ++- grovedb-version/src/version/v1.rs | 52 +++++++++ grovedb/src/batch/mod.rs | 107 +++++++++++++----- grovedb/src/element/delete.rs | 29 ++++- grovedb/src/element/exists.rs | 46 ++------ grovedb/src/element/get.rs | 76 ++++++++----- grovedb/src/element/helpers.rs | 61 +++++----- grovedb/src/element/insert.rs | 88 +++++++++++++- grovedb/src/element/query.rs | 70 +++++++++++- grovedb/src/element/serialize.rs | 51 ++++----- grovedb/src/lib.rs | 28 ----- 11 files changed, 433 insertions(+), 193 deletions(-) diff --git a/grovedb-version/src/version/grovedb_versions.rs b/grovedb-version/src/version/grovedb_versions.rs index cb71d7e4..6edf0400 100644 --- a/grovedb-version/src/version/grovedb_versions.rs +++ b/grovedb-version/src/version/grovedb_versions.rs @@ -2,9 +2,26 @@ use versioned_feature_core::FeatureVersion; #[derive(Clone, Debug, Default)] pub struct GroveDBVersions { + pub apply_batch: GroveDBApplyBatchVersions, + pub element: GroveDBElementMethodVersions, pub operations: GroveDBOperationsVersions, } +#[derive(Clone, Debug, Default)] +pub struct GroveDBApplyBatchVersions { + pub apply_batch_structure: FeatureVersion, + pub apply_body: FeatureVersion, + pub continue_partial_apply_body: FeatureVersion, + pub apply_operations_without_batching: FeatureVersion, + pub apply_batch: FeatureVersion, + pub apply_partial_batch: FeatureVersion, + pub open_batch_transactional_merk_at_path: FeatureVersion, + pub open_batch_merk_at_path: FeatureVersion, + pub apply_batch_with_element_flags_update: FeatureVersion, + pub apply_partial_batch_with_element_flags_update: FeatureVersion, + pub estimated_case_operations_for_batch: FeatureVersion, +} + #[derive(Clone, Debug, Default)] pub struct GroveDBOperationsVersions { pub get: GroveDBOperationsGetVersions, @@ -156,7 +173,6 @@ pub struct GroveDBElementMethodVersions { pub get_path_query: FeatureVersion, pub get_sized_query: FeatureVersion, pub path_query_push: FeatureVersion, - pub subquery_paths_and_value_for_sized_query: FeatureVersion, pub query_item: FeatureVersion, pub basic_push: FeatureVersion, pub serialize: FeatureVersion, diff --git a/grovedb-version/src/version/v1.rs b/grovedb-version/src/version/v1.rs index 7336d733..6012750e 100644 --- a/grovedb-version/src/version/v1.rs +++ b/grovedb-version/src/version/v1.rs @@ -7,10 +7,62 @@ use crate::version::{ }, GroveVersion, }; +use crate::version::grovedb_versions::{GroveDBApplyBatchVersions, GroveDBElementMethodVersions}; pub const GROVE_V1: GroveVersion = GroveVersion { protocol_version: 0, grovedb_versions: GroveDBVersions { + apply_batch: GroveDBApplyBatchVersions { + apply_batch_structure: 0, + apply_body: 0, + continue_partial_apply_body: 0, + apply_operations_without_batching: 0, + apply_batch: 0, + apply_partial_batch: 0, + open_batch_transactional_merk_at_path: 0, + open_batch_merk_at_path: 0, + apply_batch_with_element_flags_update: 0, + apply_partial_batch_with_element_flags_update: 0, + estimated_case_operations_for_batch: 0, + }, + element: GroveDBElementMethodVersions { + delete: 0, + delete_with_sectioned_removal_bytes: 0, + delete_into_batch_operations: 0, + element_at_key_already_exists: 0, + get: 0, + get_optional: 0, + get_from_storage: 0, + get_optional_from_storage: 0, + get_with_absolute_refs: 0, + get_value_hash: 0, + get_specialized_cost: 0, + value_defined_cost: 0, + value_defined_cost_for_serialized_value: 0, + specialized_costs_for_key_value: 0, + required_item_space: 0, + insert: 0, + insert_into_batch_operations: 0, + insert_if_not_exists: 0, + insert_if_not_exists_into_batch_operations: 0, + insert_if_changed_value: 0, + insert_if_changed_value_into_batch_operations: 0, + insert_reference: 0, + insert_reference_into_batch_operations: 0, + insert_subtree: 0, + insert_subtree_into_batch_operations: 0, + get_query: 0, + get_query_values: 0, + get_query_apply_function: 0, + get_path_query: 0, + get_sized_query: 0, + path_query_push: 0, + query_item: 0, + basic_push: 0, + serialize: 0, + serialized_size: 0, + deserialize: 0, + }, operations: GroveDBOperationsVersions { get: GroveDBOperationsGetVersions { get: 0, diff --git a/grovedb/src/batch/mod.rs b/grovedb/src/batch/mod.rs index 40c23033..7a2d626c 100644 --- a/grovedb/src/batch/mod.rs +++ b/grovedb/src/batch/mod.rs @@ -1,31 +1,3 @@ -// MIT LICENSE -// -// Copyright (c) 2021 Dash Core Group -// -// Permission is hereby granted, free of charge, to any -// person obtaining a copy of this software and associated -// documentation files (the "Software"), to deal in the -// Software without restriction, including without -// limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice -// shall be included in all copies or substantial portions -// of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - //! Apply multiple GroveDB operations atomically. mod batch_structure; @@ -91,8 +63,10 @@ use grovedb_version::version::GroveVersion; use grovedb_visualize::{Drawer, Visualize}; use integer_encoding::VarInt; use itertools::Itertools; +use grovedb_version::check_v0_with_cost; use key_info::{KeyInfo, KeyInfo::KnownKey}; pub use options::BatchApplyOptions; +use grovedb_version::error::GroveVersionError; pub use crate::batch::batch_structure::{OpsByLevelPath, OpsByPath}; #[cfg(feature = "estimated_costs")] @@ -1444,6 +1418,13 @@ impl GroveDb { u32, ) -> Result<(StorageRemovedBytes, StorageRemovedBytes), Error>, { + check_v0_with_cost!( + "apply_batch_structure", + grove_version + .grovedb_versions + .apply_batch + .apply_batch_structure + ); let mut cost = OperationCost::default(); let BatchStructure { mut ops_by_level_paths, @@ -1654,6 +1635,13 @@ impl GroveDb { get_merk_fn: impl FnMut(&[Vec], bool) -> CostResult, Error>, grove_version: &GroveVersion, ) -> CostResult, Error> { + check_v0_with_cost!( + "apply_body", + grove_version + .grovedb_versions + .apply_batch + .apply_body + ); let mut cost = OperationCost::default(); let batch_structure = cost_return_on_error!( &mut cost, @@ -1695,6 +1683,13 @@ impl GroveDb { get_merk_fn: impl FnMut(&[Vec], bool) -> CostResult, Error>, grove_version: &GroveVersion, ) -> CostResult, Error> { + check_v0_with_cost!( + "continue_partial_apply_body", + grove_version + .grovedb_versions + .apply_batch + .continue_partial_apply_body + ); let mut cost = OperationCost::default(); let batch_structure = cost_return_on_error!( &mut cost, @@ -1721,6 +1716,13 @@ impl GroveDb { transaction: TransactionArg, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "apply_operations_without_batching", + grove_version + .grovedb_versions + .apply_batch + .apply_operations_without_batching + ); let mut cost = OperationCost::default(); for op in ops.into_iter() { match op.op { @@ -1768,6 +1770,13 @@ impl GroveDb { transaction: TransactionArg, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "apply_batch", + grove_version + .grovedb_versions + .apply_batch + .apply_batch + ); self.apply_batch_with_element_flags_update( ops, batch_apply_options, @@ -1795,6 +1804,13 @@ impl GroveDb { transaction: TransactionArg, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "apply_partial_batch", + grove_version + .grovedb_versions + .apply_batch + .apply_partial_batch + ); self.apply_partial_batch_with_element_flags_update( ops, batch_apply_options, @@ -1821,6 +1837,13 @@ impl GroveDb { new_merk: bool, grove_version: &GroveVersion, ) -> CostResult>, Error> { + check_v0_with_cost!( + "open_batch_transactional_merk_at_path", + grove_version + .grovedb_versions + .apply_batch + .open_batch_transactional_merk_at_path + ); let mut cost = OperationCost::default(); let storage = self .db @@ -1901,6 +1924,13 @@ impl GroveDb { new_merk: bool, grove_version: &GroveVersion, ) -> CostResult, Error> { + check_v0_with_cost!( + "open_batch_merk_at_path", + grove_version + .grovedb_versions + .apply_batch + .open_batch_merk_at_path + ); let mut local_cost = OperationCost::default(); let storage = self .db @@ -1976,6 +2006,13 @@ impl GroveDb { transaction: TransactionArg, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "apply_batch_with_element_flags_update", + grove_version + .grovedb_versions + .apply_batch + .apply_batch_with_element_flags_update + ); let mut cost = OperationCost::default(); if ops.is_empty() { @@ -2101,6 +2138,13 @@ impl GroveDb { transaction: TransactionArg, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "apply_partial_batch_with_element_flags_update", + grove_version + .grovedb_versions + .apply_batch + .apply_partial_batch_with_element_flags_update + ); let mut cost = OperationCost::default(); if ops.is_empty() { @@ -2338,6 +2382,13 @@ impl GroveDb { >, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "estimated_case_operations_for_batch", + grove_version + .grovedb_versions + .apply_batch + .estimated_case_operations_for_batch + ); let mut cost = OperationCost::default(); if ops.is_empty() { diff --git a/grovedb/src/element/delete.rs b/grovedb/src/element/delete.rs index c29828fb..96f7ad0e 100644 --- a/grovedb/src/element/delete.rs +++ b/grovedb/src/element/delete.rs @@ -7,10 +7,16 @@ use grovedb_costs::{storage_cost::removal::StorageRemovedBytes, CostResult, Cost use grovedb_merk::{BatchEntry, Error as MerkError, Merk, MerkOptions, Op}; #[cfg(feature = "full")] use grovedb_storage::StorageContext; +#[cfg(feature = "full")] +use grovedb_version::check_v0_with_cost; +#[cfg(feature = "full")] use grovedb_version::version::GroveVersion; - +#[cfg(feature = "full")] +use grovedb_costs::OperationCost; #[cfg(feature = "full")] use crate::{Element, Error}; +#[cfg(feature = "full")] +use grovedb_version::error::GroveVersionError; impl Element { #[cfg(feature = "full")] @@ -23,6 +29,13 @@ impl Element { is_sum: bool, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "delete", + grove_version + .grovedb_versions + .element + .delete + ); let op = match (is_sum, is_layered) { (true, true) => Op::DeleteLayeredMaybeSpecialized, (true, false) => Op::DeleteMaybeSpecialized, @@ -63,6 +76,13 @@ impl Element { >, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "delete_with_sectioned_removal_bytes", + grove_version + .grovedb_versions + .element + .delete_with_sectioned_removal_bytes + ); let op = match (is_in_sum_tree, is_layered) { (true, true) => Op::DeleteLayeredMaybeSpecialized, (true, false) => Op::DeleteMaybeSpecialized, @@ -96,6 +116,13 @@ impl Element { batch_operations: &mut Vec>, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "delete_into_batch_operations", + grove_version + .grovedb_versions + .element + .delete_into_batch_operations + ); let op = match (is_sum, is_layered) { (true, true) => Op::DeleteLayeredMaybeSpecialized, (true, false) => Op::DeleteMaybeSpecialized, diff --git a/grovedb/src/element/exists.rs b/grovedb/src/element/exists.rs index 936fe726..8b383ab3 100644 --- a/grovedb/src/element/exists.rs +++ b/grovedb/src/element/exists.rs @@ -1,47 +1,18 @@ -// MIT LICENSE -// -// Copyright (c) 2021 Dash Core Group -// -// Permission is hereby granted, free of charge, to any -// person obtaining a copy of this software and associated -// documentation files (the "Software"), to deal in the -// Software without restriction, including without -// limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice -// shall be included in all copies or substantial portions -// of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - //! Exists //! Implements in Element functions for checking if stuff exists -#[cfg(feature = "full")] use grovedb_costs::CostResult; -#[cfg(feature = "full")] use grovedb_merk::Merk; -#[cfg(feature = "full")] use grovedb_storage::StorageContext; +use grovedb_version::check_v0_with_cost; use grovedb_version::version::GroveVersion; - -#[cfg(feature = "full")] use crate::{Element, Error}; +use grovedb_costs::OperationCost; +use grovedb_version::error::GroveVersionError; +use grovedb_costs::CostsExt; impl Element { - #[cfg(feature = "full")] + /// Helper function that returns whether an element at the key for the /// element already exists. pub fn element_at_key_already_exists<'db, K: AsRef<[u8]>, S: StorageContext<'db>>( @@ -50,6 +21,13 @@ impl Element { key: K, grove_version: &GroveVersion, ) -> CostResult { + check_v0_with_cost!( + "element_at_key_already_exists", + grove_version + .grovedb_versions + .element + .element_at_key_already_exists + ); merk.exists( key.as_ref(), Some(&Element::value_defined_cost_for_serialized_value), diff --git a/grovedb/src/element/get.rs b/grovedb/src/element/get.rs index aacf34e3..1034230f 100644 --- a/grovedb/src/element/get.rs +++ b/grovedb/src/element/get.rs @@ -1,31 +1,3 @@ -// MIT LICENSE -// -// Copyright (c) 2021 Dash Core Group -// -// Permission is hereby granted, free of charge, to any -// person obtaining a copy of this software and associated -// documentation files (the "Software"), to deal in the -// Software without restriction, including without -// limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice -// shall be included in all copies or substantial portions -// of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - //! Get //! Implements functions in Element for getting @@ -42,10 +14,11 @@ use grovedb_merk::{ed::Decode, tree::TreeNodeInner}; use grovedb_storage::StorageContext; use grovedb_version::version::GroveVersion; use integer_encoding::VarInt; - +use grovedb_version::check_v0_with_cost; use crate::element::{SUM_ITEM_COST_SIZE, SUM_TREE_COST_SIZE, TREE_COST_SIZE}; #[cfg(feature = "full")] use crate::{Element, Error, Hash}; +use grovedb_version::error::GroveVersionError; impl Element { #[cfg(feature = "full")] @@ -57,6 +30,13 @@ impl Element { allow_cache: bool, grove_version: &GroveVersion, ) -> CostResult { + check_v0_with_cost!( + "get", + grove_version + .grovedb_versions + .element + .get + ); Self::get_optional(merk, key.as_ref(), allow_cache, grove_version).map(|result| { let value = result?; value.ok_or_else(|| { @@ -81,6 +61,13 @@ impl Element { allow_cache: bool, grove_version: &GroveVersion, ) -> CostResult, Error> { + check_v0_with_cost!( + "get_optional", + grove_version + .grovedb_versions + .element + .get_optional + ); let mut cost = OperationCost::default(); let value_opt = cost_return_on_error!( @@ -116,6 +103,13 @@ impl Element { key: K, grove_version: &GroveVersion, ) -> CostResult { + check_v0_with_cost!( + "get_from_storage", + grove_version + .grovedb_versions + .element + .get_from_storage + ); Self::get_optional_from_storage(storage, key.as_ref(), grove_version).map(|result| { let value = result?; value.ok_or_else(|| { @@ -135,6 +129,13 @@ impl Element { key: K, grove_version: &GroveVersion, ) -> CostResult, Error> { + check_v0_with_cost!( + "get_optional_from_storage", + grove_version + .grovedb_versions + .element + .get_optional_from_storage + ); let mut cost = OperationCost::default(); let key_ref = key.as_ref(); let node_value_opt = cost_return_on_error!( @@ -222,6 +223,13 @@ impl Element { allow_cache: bool, grove_version: &GroveVersion, ) -> CostResult { + check_v0_with_cost!( + "get_with_absolute_refs", + grove_version + .grovedb_versions + .element + .get_with_absolute_refs + ); let mut cost = OperationCost::default(); let element = cost_return_on_error!( @@ -233,8 +241,7 @@ impl Element { &cost, element.convert_if_reference_to_absolute_reference( path, - Some(key.as_ref()), - grove_version + Some(key.as_ref()) ) ); @@ -249,6 +256,13 @@ impl Element { allow_cache: bool, grove_version: &GroveVersion, ) -> CostResult, Error> { + check_v0_with_cost!( + "get_value_hash", + grove_version + .grovedb_versions + .element + .get_value_hash + ); let mut cost = OperationCost::default(); let value_hash = cost_return_on_error!( diff --git a/grovedb/src/element/helpers.rs b/grovedb/src/element/helpers.rs index 59838e1f..a4926295 100644 --- a/grovedb/src/element/helpers.rs +++ b/grovedb/src/element/helpers.rs @@ -1,31 +1,3 @@ -// MIT LICENSE -// -// Copyright (c) 2021 Dash Core Group -// -// Permission is hereby granted, free of charge, to any -// person obtaining a copy of this software and associated -// documentation files (the "Software"), to deal in the -// Software without restriction, including without -// limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice -// shall be included in all copies or substantial portions -// of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - //! Helpers //! Implements helper functions in Element @@ -43,7 +15,7 @@ use grovedb_merk::{ use grovedb_version::version::GroveVersion; #[cfg(feature = "full")] use integer_encoding::VarInt; - +use grovedb_version::check_v0; #[cfg(feature = "full")] use crate::reference_path::path_from_reference_path_type; #[cfg(any(feature = "full", feature = "verify"))] @@ -55,6 +27,7 @@ use crate::{ }; #[cfg(any(feature = "full", feature = "verify"))] use crate::{Element, Error}; +use grovedb_version::error::GroveVersionError; impl Element { #[cfg(any(feature = "full", feature = "verify"))] @@ -219,8 +192,15 @@ impl Element { #[cfg(feature = "full")] /// Get the required item space - pub fn required_item_space(len: u32, flag_len: u32, grove_version: &GroveVersion) -> u32 { - len + len.required_space() as u32 + flag_len + flag_len.required_space() as u32 + 1 + pub fn required_item_space(len: u32, flag_len: u32, grove_version: &GroveVersion) -> Result { + check_v0!( + "required_item_space", + grove_version + .grovedb_versions + .element + .required_item_space + ); + Ok(len + len.required_space() as u32 + flag_len + flag_len.required_space() as u32 + 1) } #[cfg(feature = "full")] @@ -229,11 +209,10 @@ impl Element { self, path: &[&[u8]], key: Option<&[u8]>, - grove_version: &GroveVersion, ) -> Result { - // Convert any non absolute reference type to an absolute one + // Convert any non-absolute reference type to an absolute one // we do this here because references are aggregated first then followed later - // to follow non absolute references, we need the path they are stored at + // to follow non-absolute references, we need the path they are stored at // this information is lost during the aggregation phase. Ok(match &self { Element::Reference(reference_path_type, ..) => match reference_path_type { @@ -263,6 +242,13 @@ impl Element { is_sum_node: bool, grove_version: &GroveVersion, ) -> Result { + check_v0!( + "specialized_costs_for_key_value", + grove_version + .grovedb_versions + .element + .specialized_costs_for_key_value + ); // todo: we actually don't need to deserialize the whole element let element = Element::deserialize(value, grove_version)?; let cost = match element { @@ -317,6 +303,13 @@ impl Element { #[cfg(feature = "full")] /// Get tree cost for the element pub fn get_specialized_cost(&self, grove_version: &GroveVersion) -> Result { + check_v0!( + "get_specialized_cost", + grove_version + .grovedb_versions + .element + .get_specialized_cost + ); match self { Element::Tree(..) => Ok(TREE_COST_SIZE), Element::SumTree(..) => Ok(SUM_TREE_COST_SIZE), diff --git a/grovedb/src/element/insert.rs b/grovedb/src/element/insert.rs index 597ec1bd..d05fb72b 100644 --- a/grovedb/src/element/insert.rs +++ b/grovedb/src/element/insert.rs @@ -2,21 +2,17 @@ //! Implements functions in Element for inserting into Merk use grovedb_costs::cost_return_on_error_default; -#[cfg(feature = "full")] use grovedb_costs::{ cost_return_on_error, cost_return_on_error_no_add, CostResult, CostsExt, OperationCost, }; -#[cfg(feature = "full")] use grovedb_merk::{BatchEntry, Error as MerkError, Merk, MerkOptions, Op, TreeFeatureType}; -#[cfg(feature = "full")] use grovedb_storage::StorageContext; use grovedb_version::version::GroveVersion; -#[cfg(feature = "full")] use integer_encoding::VarInt; - +use grovedb_version::check_v0_with_cost; use crate::Element::SumItem; -#[cfg(feature = "full")] use crate::{Element, Error, Hash}; +use grovedb_version::error::GroveVersionError; impl Element { #[cfg(feature = "full")] @@ -32,6 +28,14 @@ impl Element { options: Option, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "insert", + grove_version + .grovedb_versions + .element + .insert + ); + let serialized = cost_return_on_error_default!(self.serialize(grove_version)); if !merk.is_sum_tree && self.is_sum_item() { @@ -83,6 +87,14 @@ impl Element { feature_type: TreeFeatureType, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "insert_into_batch_operations", + grove_version + .grovedb_versions + .element + .insert_into_batch_operations + ); + let serialized = match self.serialize(grove_version) { Ok(s) => s, Err(e) => return Err(e).wrap_with_cost(Default::default()), @@ -121,6 +133,14 @@ impl Element { options: Option, grove_version: &GroveVersion, ) -> CostResult { + check_v0_with_cost!( + "insert_if_not_exists", + grove_version + .grovedb_versions + .element + .insert_if_not_exists + ); + let mut cost = OperationCost::default(); let exists = cost_return_on_error!( &mut cost, @@ -149,6 +169,14 @@ impl Element { feature_type: TreeFeatureType, grove_version: &GroveVersion, ) -> CostResult { + check_v0_with_cost!( + "insert_if_not_exists_into_batch_operations", + grove_version + .grovedb_versions + .element + .insert_if_not_exists_into_batch_operations + ); + let mut cost = OperationCost::default(); let exists = cost_return_on_error!( &mut cost, @@ -185,6 +213,14 @@ impl Element { options: Option, grove_version: &GroveVersion, ) -> CostResult<(bool, Option), Error> { + check_v0_with_cost!( + "insert_if_changed_value", + grove_version + .grovedb_versions + .element + .insert_if_changed_value + ); + let mut cost = OperationCost::default(); let previous_element = cost_return_on_error!( &mut cost, @@ -219,6 +255,14 @@ impl Element { feature_type: TreeFeatureType, grove_version: &GroveVersion, ) -> CostResult<(bool, Option), Error> { + check_v0_with_cost!( + "insert_if_changed_value_into_batch_operations", + grove_version + .grovedb_versions + .element + .insert_if_changed_value_into_batch_operations + ); + let mut cost = OperationCost::default(); let previous_element = cost_return_on_error!( &mut cost, @@ -258,6 +302,14 @@ impl Element { options: Option, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "insert_reference", + grove_version + .grovedb_versions + .element + .insert_reference + ); + let serialized = match self.serialize(grove_version) { Ok(s) => s, Err(e) => return Err(e).wrap_with_cost(Default::default()), @@ -300,6 +352,14 @@ impl Element { feature_type: TreeFeatureType, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "insert_reference_into_batch_operations", + grove_version + .grovedb_versions + .element + .insert_reference_into_batch_operations + ); + let serialized = match self.serialize(grove_version) { Ok(s) => s, Err(e) => return Err(e).wrap_with_cost(Default::default()), @@ -327,6 +387,14 @@ impl Element { options: Option, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "insert_subtree", + grove_version + .grovedb_versions + .element + .insert_subtree + ); + let serialized = match self.serialize(grove_version) { Ok(s) => s, Err(e) => return Err(e).wrap_with_cost(Default::default()), @@ -374,6 +442,14 @@ impl Element { feature_type: TreeFeatureType, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "insert_subtree_into_batch_operations", + grove_version + .grovedb_versions + .element + .insert_subtree_into_batch_operations + ); + let serialized = match self.serialize(grove_version) { Ok(s) => s, Err(e) => return Err(e).wrap_with_cost(Default::default()), diff --git a/grovedb/src/element/query.rs b/grovedb/src/element/query.rs index 7a13e97e..39573b18 100644 --- a/grovedb/src/element/query.rs +++ b/grovedb/src/element/query.rs @@ -18,6 +18,7 @@ use grovedb_merk::proofs::Query; use grovedb_path::SubtreePath; #[cfg(feature = "full")] use grovedb_storage::{rocksdb_storage::RocksDbStorage, RawIterator, StorageContext}; +use grovedb_version::{check_v0, check_v0_with_cost}; use grovedb_version::version::GroveVersion; #[cfg(feature = "full")] @@ -37,6 +38,7 @@ use crate::{ }; #[cfg(any(feature = "full", feature = "verify"))] use crate::{query_result_type::Path, Element, SizedQuery}; +use grovedb_version::error::GroveVersionError; #[cfg(any(feature = "full", feature = "verify"))] #[derive(Copy, Clone, Debug)] @@ -236,6 +238,14 @@ impl Element { transaction: TransactionArg, grove_version: &GroveVersion, ) -> CostResult { + check_v0_with_cost!( + "insert_subtree_into_batch_operations", + grove_version + .grovedb_versions + .element + .get_query + ); + let sized_query = SizedQuery::new(query.clone(), None, None); Element::get_sized_query( storage, @@ -259,6 +269,14 @@ impl Element { transaction: TransactionArg, grove_version: &GroveVersion, ) -> CostResult, Error> { + check_v0_with_cost!( + "get_query_values", + grove_version + .grovedb_versions + .element + .get_query_values + ); + Element::get_query( storage, merk_path, @@ -295,6 +313,14 @@ impl Element { add_element_function: fn(PathQueryPushArgs, &GroveVersion) -> CostResult<(), Error>, grove_version: &GroveVersion, ) -> CostResult<(QueryResultElements, u16), Error> { + check_v0_with_cost!( + "get_query_apply_function", + grove_version + .grovedb_versions + .element + .get_query_apply_function + ); + let mut cost = OperationCost::default(); let mut results = Vec::new(); @@ -370,6 +396,14 @@ impl Element { transaction: TransactionArg, grove_version: &GroveVersion, ) -> CostResult<(QueryResultElements, u16), Error> { + check_v0_with_cost!( + "get_path_query", + grove_version + .grovedb_versions + .element + .get_path_query + ); + let path_slices = path_query .path .iter() @@ -398,6 +432,14 @@ impl Element { transaction: TransactionArg, grove_version: &GroveVersion, ) -> CostResult<(QueryResultElements, u16), Error> { + check_v0_with_cost!( + "get_sized_query", + grove_version + .grovedb_versions + .element + .get_sized_query + ); + Element::get_query_apply_function( storage, path, @@ -416,6 +458,14 @@ impl Element { args: PathQueryPushArgs, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "path_query_push", + grove_version + .grovedb_versions + .element + .path_query_push + ); + // println!("path_query_push {} \n", args); let mut cost = OperationCost::default(); @@ -649,7 +699,7 @@ impl Element { #[cfg(any(feature = "full", feature = "verify"))] /// Takes a sized query and a key and returns subquery key and subquery as /// tuple - pub fn subquery_paths_and_value_for_sized_query( + fn subquery_paths_and_value_for_sized_query( sized_query: &SizedQuery, key: &[u8], ) -> (Option, Option) { @@ -703,6 +753,14 @@ impl Element { add_element_function: fn(PathQueryPushArgs, &GroveVersion) -> CostResult<(), Error>, grove_version: &GroveVersion, ) -> CostResult<(), Error> { + check_v0_with_cost!( + "query_item", + grove_version + .grovedb_versions + .element + .query_item + ); + let mut cost = OperationCost::default(); let subtree_path: SubtreePath<_> = path.into(); @@ -853,6 +911,14 @@ impl Element { #[cfg(feature = "full")] fn basic_push(args: PathQueryPushArgs, grove_version: &GroveVersion) -> Result<(), Error> { + check_v0!( + "basic_push", + grove_version + .grovedb_versions + .element + .basic_push + ); + // println!("basic_push {}", args); let PathQueryPushArgs { path, @@ -866,7 +932,7 @@ impl Element { } = args; let element = - element.convert_if_reference_to_absolute_reference(path, key, grove_version)?; + element.convert_if_reference_to_absolute_reference(path, key)?; if offset.unwrap_or(0) == 0 { match result_type { diff --git a/grovedb/src/element/serialize.rs b/grovedb/src/element/serialize.rs index 88545116..44b07195 100644 --- a/grovedb/src/element/serialize.rs +++ b/grovedb/src/element/serialize.rs @@ -1,44 +1,25 @@ -// MIT LICENSE -// -// Copyright (c) 2021 Dash Core Group -// -// Permission is hereby granted, free of charge, to any -// person obtaining a copy of this software and associated -// documentation files (the "Software"), to deal in the -// Software without restriction, including without -// limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice -// shall be included in all copies or substantial portions -// of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - //! Serialize //! Implements serialization functions in Element use bincode::config; +use grovedb_version::check_v0; use grovedb_version::version::GroveVersion; #[cfg(any(feature = "full", feature = "verify"))] use crate::{Element, Error}; +use grovedb_version::error::GroveVersionError; impl Element { #[cfg(feature = "full")] /// Serializes self. Returns vector of u8s. pub fn serialize(&self, grove_version: &GroveVersion) -> Result, Error> { + check_v0!( + "Element::serialize", + grove_version + .grovedb_versions + .element + .serialize + ); let config = config::standard().with_big_endian().with_no_limit(); bincode::encode_to_vec(self, config) .map_err(|e| Error::CorruptedData(format!("unable to serialize element {}", e))) @@ -47,6 +28,13 @@ impl Element { #[cfg(feature = "full")] /// Serializes self. Returns usize. pub fn serialized_size(&self, grove_version: &GroveVersion) -> Result { + check_v0!( + "Element::serialized_size", + grove_version + .grovedb_versions + .element + .serialized_size + ); self.serialize(grove_version) .map(|serialized| serialized.len()) } @@ -54,6 +42,13 @@ impl Element { #[cfg(any(feature = "full", feature = "verify"))] /// Deserializes given bytes and sets as self pub fn deserialize(bytes: &[u8], grove_version: &GroveVersion) -> Result { + check_v0!( + "Element::deserialize", + grove_version + .grovedb_versions + .element + .deserialize + ); let config = config::standard().with_big_endian().with_no_limit(); Ok(bincode::decode_from_slice(bytes, config) .map_err(|e| Error::CorruptedData(format!("unable to deserialize element {}", e)))? diff --git a/grovedb/src/lib.rs b/grovedb/src/lib.rs index cb11cc30..012785ca 100644 --- a/grovedb/src/lib.rs +++ b/grovedb/src/lib.rs @@ -1,31 +1,3 @@ -// MIT LICENSE -// -// Copyright (c) 2021 Dash Core Group -// -// Permission is hereby granted, free of charge, to any -// person obtaining a copy of this software and associated -// documentation files (the "Software"), to deal in the -// Software without restriction, including without -// limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice -// shall be included in all copies or substantial portions -// of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - //! GroveDB is a database that enables cryptographic proofs for complex queries. //! //! # Examples