diff --git a/costs/Cargo.toml b/costs/Cargo.toml index 6aaa6ece..4d62b58e 100644 --- a/costs/Cargo.toml +++ b/costs/Cargo.toml @@ -10,6 +10,6 @@ repository = "https://github.com/dashpay/grovedb" [dependencies] -thiserror = "1.0.30" +thiserror = "1.0.58" intmap = "2.0.0" -integer-encoding = "3.0.3" +integer-encoding = "4.0.0" diff --git a/grovedb/Cargo.toml b/grovedb/Cargo.toml index c479b07c..a77ff4e9 100644 --- a/grovedb/Cargo.toml +++ b/grovedb/Cargo.toml @@ -13,26 +13,25 @@ documentation = "https://docs.rs/grovedb" [dependencies] grovedb-merk = { version = "1.0.0-rc.2", path = "../merk", optional = true, default-features = false } -thiserror = { version = "1.0.37", optional = true } -tempfile = { version = "3.3.0", optional = true } -bincode = { version = "1.3.3", optional = true } -serde = { version = "1.0.149", optional = true } +thiserror = { version = "1.0.58", optional = true } +tempfile = { version = "3.10.1", optional = true } +bincode = { version = "2.0.0-rc.3" } grovedb-storage = { version = "1.0.0-rc.2", path = "../storage", optional = true } grovedb-visualize = { version = "1.0.0-rc.2", path = "../visualize", optional = true } hex = { version = "0.4.3", optional = true } -itertools = { version = "0.10.5", optional = true } -integer-encoding = { version = "3.0.4", optional = true } +itertools = { version = "0.12.1", optional = true } +integer-encoding = { version = "4.0.0", optional = true } grovedb-costs = { version = "1.0.0-rc.2", path = "../costs", optional = true } nohash-hasher = { version = "0.2.0", optional = true } -indexmap = { version = "1.9.2", optional = true } +indexmap = { version = "2.2.6", optional = true } intmap = { version = "2.0.0", optional = true } grovedb-path = { version = "1.0.0-rc.2", path = "../path" } [dev-dependencies] rand = "0.8.5" -criterion = "0.4.0" +criterion = "0.5.1" hex = "0.4.3" -pretty_assertions = "1.3.0" +pretty_assertions = "1.4.0" [[bench]] name = "insertion_benchmark" @@ -44,8 +43,6 @@ full = [ "grovedb-merk/full", "thiserror", "tempfile", - "bincode", - "serde/derive", "grovedb-storage/rocksdb_storage", "visualize", "hex", @@ -63,8 +60,6 @@ verify = [ "grovedb-merk/verify", "grovedb-costs", "thiserror", - "serde/derive", - "bincode", "integer-encoding", ] estimated_costs = ["full"] diff --git a/grovedb/src/element/mod.rs b/grovedb/src/element/mod.rs index f674d2d8..a5573b4d 100644 --- a/grovedb/src/element/mod.rs +++ b/grovedb/src/element/mod.rs @@ -49,14 +49,13 @@ mod serialize; #[cfg(feature = "full")] use core::fmt; +use bincode::{Decode, Encode}; #[cfg(any(feature = "full", feature = "verify"))] use grovedb_merk::estimated_costs::SUM_VALUE_EXTRA_COST; #[cfg(feature = "full")] use grovedb_merk::estimated_costs::{LAYER_COST_SIZE, SUM_LAYER_COST_SIZE}; #[cfg(feature = "full")] use grovedb_visualize::visualize_to_vec; -#[cfg(any(feature = "full", feature = "verify"))] -use serde::{Deserialize, Serialize}; #[cfg(any(feature = "full", feature = "verify"))] use crate::reference_path::ReferencePathType; @@ -93,7 +92,7 @@ pub type SumValue = i64; /// /// ONLY APPEND TO THIS LIST!!! Because /// of how serialization works. -#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] +#[derive(Clone, Encode, Decode, PartialEq, Eq, Hash)] #[cfg_attr(not(any(feature = "full", feature = "visualize")), derive(Debug))] pub enum Element { /// An ordinary value diff --git a/grovedb/src/element/serialize.rs b/grovedb/src/element/serialize.rs index 730881d2..ab798054 100644 --- a/grovedb/src/element/serialize.rs +++ b/grovedb/src/element/serialize.rs @@ -29,8 +29,7 @@ //! Serialize //! Implements serialization functions in Element -#[cfg(any(feature = "full", feature = "verify"))] -use bincode::Options; +use bincode::config; #[cfg(any(feature = "full", feature = "verify"))] use crate::{Element, Error}; @@ -39,31 +38,26 @@ impl Element { #[cfg(feature = "full")] /// Serializes self. Returns vector of u8s. pub fn serialize(&self) -> Result, Error> { - bincode::DefaultOptions::default() - .with_varint_encoding() - .reject_trailing_bytes() - .serialize(self) - .map_err(|_| Error::CorruptedData(String::from("unable to serialize element"))) + let config = bincode::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))) } #[cfg(feature = "full")] /// Serializes self. Returns usize. - pub fn serialized_size(&self) -> usize { - bincode::DefaultOptions::default() - .with_varint_encoding() - .reject_trailing_bytes() - .serialized_size(self) - .unwrap() as usize // this should not be able to error + pub fn serialized_size(&self) -> Result { + self.serialize().map(|serialized| serialized.len()) } #[cfg(any(feature = "full", feature = "verify"))] /// Deserializes given bytes and sets as self pub fn deserialize(bytes: &[u8]) -> Result { - bincode::DefaultOptions::default() - .with_varint_encoding() - .reject_trailing_bytes() - .deserialize(bytes) - .map_err(|_| Error::CorruptedData(String::from("unable to deserialize element"))) + 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)))? + .0) } } @@ -80,20 +74,20 @@ mod tests { let empty_tree = Element::empty_tree(); let serialized = empty_tree.serialize().expect("expected to serialize"); assert_eq!(serialized.len(), 3); - assert_eq!(serialized.len(), empty_tree.serialized_size()); + assert_eq!(serialized.len(), empty_tree.serialized_size().unwrap()); // The tree is fixed length 32 bytes, so it's enum 2 then 32 bytes of zeroes assert_eq!(hex::encode(serialized), "020000"); let empty_tree = Element::new_tree_with_flags(None, Some(vec![5])); let serialized = empty_tree.serialize().expect("expected to serialize"); assert_eq!(serialized.len(), 5); - assert_eq!(serialized.len(), empty_tree.serialized_size()); + assert_eq!(serialized.len(), empty_tree.serialized_size().unwrap()); assert_eq!(hex::encode(serialized), "0200010105"); let item = Element::new_item(hex::decode("abcdef").expect("expected to decode")); let serialized = item.serialize().expect("expected to serialize"); assert_eq!(serialized.len(), 6); - assert_eq!(serialized.len(), item.serialized_size()); + assert_eq!(serialized.len(), item.serialized_size().unwrap()); // The item is variable length 3 bytes, so it's enum 2 then 32 bytes of zeroes assert_eq!(hex::encode(serialized), "0003abcdef00"); @@ -102,7 +96,7 @@ mod tests { let item = Element::new_sum_item(5); let serialized = item.serialize().expect("expected to serialize"); assert_eq!(serialized.len(), 3); - assert_eq!(serialized.len(), item.serialized_size()); + assert_eq!(serialized.len(), item.serialized_size().unwrap()); // The item is variable length 3 bytes, so it's enum 2 then 32 bytes of zeroes assert_eq!(hex::encode(serialized), "030a00"); @@ -112,7 +106,7 @@ mod tests { ); let serialized = item.serialize().expect("expected to serialize"); assert_eq!(serialized.len(), 8); - assert_eq!(serialized.len(), item.serialized_size()); + assert_eq!(serialized.len(), item.serialized_size().unwrap()); assert_eq!(hex::encode(serialized), "0003abcdef010101"); let reference = Element::new_reference(ReferencePathType::AbsolutePathReference(vec![ @@ -122,7 +116,7 @@ mod tests { ])); let serialized = reference.serialize().expect("expected to serialize"); assert_eq!(serialized.len(), 12); - assert_eq!(serialized.len(), reference.serialized_size()); + assert_eq!(serialized.len(), reference.serialized_size().unwrap()); // The item is variable length 2 bytes, so it's enum 1 then 1 byte for length, // then 1 byte for 0, then 1 byte 02 for abcd, then 1 byte '1' for 05 assert_eq!(hex::encode(serialized), "010003010002abcd01050000"); @@ -137,7 +131,7 @@ mod tests { ); let serialized = reference.serialize().expect("expected to serialize"); assert_eq!(serialized.len(), 16); - assert_eq!(serialized.len(), reference.serialized_size()); + assert_eq!(serialized.len(), reference.serialized_size().unwrap()); assert_eq!(hex::encode(serialized), "010003010002abcd0105000103010203"); } } diff --git a/grovedb/src/estimated_costs/average_case_costs.rs b/grovedb/src/estimated_costs/average_case_costs.rs index d93b6451..8d803daf 100644 --- a/grovedb/src/estimated_costs/average_case_costs.rs +++ b/grovedb/src/estimated_costs/average_case_costs.rs @@ -208,7 +208,7 @@ impl GroveDb { _ => add_cost_case_merk_insert( &mut cost, key_len, - value.serialized_size() as u32, + cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32, in_tree_using_sums, ), }; @@ -259,7 +259,7 @@ impl GroveDb { let sum_item_cost_size = if value.is_sum_item() { SUM_ITEM_COST_SIZE } else { - value.serialized_size() as u32 + cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32 }; let value_len = sum_item_cost_size + flags_len; add_cost_case_merk_replace_same_size( @@ -272,7 +272,7 @@ impl GroveDb { _ => add_cost_case_merk_replace_same_size( &mut cost, key_len, - value.serialized_size() as u32, + cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32, in_tree_using_sums, ), }; @@ -303,7 +303,8 @@ impl GroveDb { flags_len + flags_len.required_space() as u32 }); // Items need to be always the same serialized size for this to work - let item_cost_size = value.serialized_size() as u32; + let item_cost_size = + cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32; let value_len = item_cost_size + flags_len; add_cost_case_merk_patch( &mut cost, @@ -562,7 +563,7 @@ mod test { &mut average_case_has_raw_cost, &path, &key, - elem.serialized_size() as u32, + elem.serialized_size().expect("expected size") as u32, false, ); diff --git a/grovedb/src/estimated_costs/worst_case_costs.rs b/grovedb/src/estimated_costs/worst_case_costs.rs index 5a72a405..106c2bb6 100644 --- a/grovedb/src/estimated_costs/worst_case_costs.rs +++ b/grovedb/src/estimated_costs/worst_case_costs.rs @@ -29,7 +29,7 @@ //! Worst case costs //! Implements worst case cost functions in GroveDb -use grovedb_costs::{CostResult, CostsExt, OperationCost}; +use grovedb_costs::{cost_return_on_error_no_add, CostResult, CostsExt, OperationCost}; use grovedb_merk::{ estimated_costs::{ add_cost_case_merk_insert, add_cost_case_merk_insert_layered, add_cost_case_merk_patch, @@ -195,7 +195,7 @@ impl GroveDb { _ => add_cost_case_merk_insert( &mut cost, key_len, - value.serialized_size() as u32, + cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32, in_parent_tree_using_sums, ), }; @@ -253,7 +253,7 @@ impl GroveDb { _ => add_cost_case_merk_replace( &mut cost, key_len, - value.serialized_size() as u32, + cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32, in_parent_tree_using_sums, ), }; @@ -284,7 +284,8 @@ impl GroveDb { flags_len + flags_len.required_space() as u32 }); // Items need to be always the same serialized size for this to work - let sum_item_cost_size = value.serialized_size() as u32; + let sum_item_cost_size = + cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32; let value_len = sum_item_cost_size + flags_len; add_cost_case_merk_patch( &mut cost, @@ -498,7 +499,7 @@ mod test { &mut worst_case_has_raw_cost, &path, &key, - elem.serialized_size() as u32, + elem.serialized_size().expect("expected size") as u32, false, ); diff --git a/grovedb/src/reference_path.rs b/grovedb/src/reference_path.rs index 68e6e621..2b9fb7ed 100644 --- a/grovedb/src/reference_path.rs +++ b/grovedb/src/reference_path.rs @@ -31,12 +31,11 @@ #[cfg(feature = "full")] use std::fmt; +use bincode::{Decode, Encode}; #[cfg(feature = "full")] use grovedb_visualize::visualize_to_vec; #[cfg(feature = "full")] use integer_encoding::VarInt; -#[cfg(any(feature = "full", feature = "verify"))] -use serde::{Deserialize, Serialize}; #[cfg(feature = "full")] use crate::Error; @@ -44,7 +43,7 @@ use crate::Error; #[cfg(any(feature = "full", feature = "verify"))] #[cfg_attr(not(any(feature = "full", feature = "visualize")), derive(Debug))] /// Reference path variants -#[derive(Hash, Eq, PartialEq, Serialize, Deserialize, Clone)] +#[derive(Hash, Eq, PartialEq, Encode, Decode, Clone)] pub enum ReferencePathType { /// Holds the absolute path to the element the reference points to AbsolutePathReference(Vec>), diff --git a/grovedb/src/visualize.rs b/grovedb/src/visualize.rs index 6bba2f83..6f1f1c0d 100644 --- a/grovedb/src/visualize.rs +++ b/grovedb/src/visualize.rs @@ -30,7 +30,10 @@ use std::io::{Result, Write}; -use bincode::Options; +use bincode::{ + config, + config::{BigEndian, Configuration}, +}; use grovedb_merk::{Merk, VisualizeableMerk}; use grovedb_path::SubtreePathBuilder; use grovedb_storage::StorageContext; @@ -239,11 +242,10 @@ impl Visualize for GroveDb { #[allow(dead_code)] pub fn visualize_merk_stdout<'db, S: StorageContext<'db>>(merk: &Merk) { visualize_stdout(&VisualizeableMerk::new(merk, |bytes: &[u8]| { - bincode::DefaultOptions::default() - .with_varint_encoding() - .reject_trailing_bytes() - .deserialize::(bytes) + let config = config::standard().with_big_endian().with_no_limit(); + bincode::decode_from_slice::>(bytes, config) .expect("unable to deserialize Element") + .0 })); } diff --git a/merk/Cargo.toml b/merk/Cargo.toml index 7d180f54..e381f5ed 100644 --- a/merk/Cargo.toml +++ b/merk/Cargo.toml @@ -11,17 +11,17 @@ readme = "README.md" documentation = "https://docs.rs/grovedb-merk" [dependencies] -thiserror = "1.0.37" +thiserror = "1.0.58" grovedb-storage = { version = "1.0.0-rc.2", path = "../storage", optional = true } failure = "0.1.8" -integer-encoding = "3.0.4" -indexmap = "1.9.2" +integer-encoding = "4.0.0" +indexmap = "2.2.6" grovedb-costs = { version = "1.0.0-rc.2", path = "../costs" } grovedb-visualize = { version = "1.0.0-rc.2", path = "../visualize" } grovedb-path = { version = "1.0.0-rc.2", path = "../path" } [dependencies.time] -version = "0.3.17" +version = "0.3.34" optional = true [dependencies.hex] @@ -29,15 +29,15 @@ version = "0.4.3" optional = true [dependencies.colored] -version = "2.0.4" +version = "2.1.0" optional = true [dependencies.num_cpus] -version = "1.14.0" +version = "1.16.0" optional = true [dependencies.byteorder] -version = "1.4.3" +version = "1.5.0" optional = true [dependencies.ed] @@ -45,7 +45,7 @@ version = "0.2.2" optional = true [dependencies.blake3] -version = "1.3.3" +version = "1.5.1" optional = true [dependencies.rand] @@ -72,8 +72,8 @@ verify = [ ] [dev-dependencies] -tempfile = "3.3.0" -criterion = "0.4.0" +tempfile = "3.10.1" +criterion = "0.5.1" [[bench]] name = "merk" diff --git a/storage/Cargo.toml b/storage/Cargo.toml index 856888a7..8dc73fdc 100644 --- a/storage/Cargo.toml +++ b/storage/Cargo.toml @@ -10,15 +10,15 @@ repository = "https://github.com/dashpay/grovedb" [dependencies] lazy_static = { version = "1.4.0", optional = true } -num_cpus = { version = "1.14.0", optional = true } -tempfile = { version = "3.3.0", optional = true } -blake3 = { version = "1.3.3", optional = true } -integer-encoding = { version = "3.0.4", optional = true } +num_cpus = { version = "1.16.0", optional = true } +tempfile = { version = "3.10.1", optional = true } +blake3 = { version = "1.5.1", optional = true } +integer-encoding = { version = "4.0.0", optional = true } grovedb-visualize = { version = "1.0.0-rc.2", path = "../visualize" } -strum = { version = "0.24.1", features = ["derive"] } +strum = { version = "0.26.2", features = ["derive"] } grovedb-costs = { version = "1.0.0-rc.2", path = "../costs" } thiserror = "1.0.37" -rocksdb = { version = "0.21.0", optional = true } +rocksdb = { version = "0.22.0", optional = true } hex = "0.4.3" grovedb-path = { version = "1.0.0-rc.2", path = "../path" } diff --git a/visualize/Cargo.toml b/visualize/Cargo.toml index f27fe48e..ac93bff0 100644 --- a/visualize/Cargo.toml +++ b/visualize/Cargo.toml @@ -12,4 +12,4 @@ repository = "https://github.com/dashpay/grovedb" [dependencies] hex = "0.4.3" -itertools = "0.10.3" +itertools = "0.12.1"