diff --git a/Cargo.lock b/Cargo.lock index f4078371..3ccb055c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2076,7 +2076,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.117", ] [[package]] @@ -9463,6 +9463,7 @@ dependencies = [ "system_accounts", "tempfile", "thiserror 2.0.18", + "zstd", ] [[package]] @@ -11799,3 +11800,31 @@ dependencies = [ "log", "simd-adler32", ] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index 88fe0c32..53b684b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -147,6 +147,7 @@ bip39 = "2.2.0" hmac-sha512 = "1.1.7" chrono = "0.4.41" borsh = "1.5.7" +zstd = "0.13" base58 = "0.2.0" itertools = "0.14.0" num-bigint = "0.4.6" diff --git a/lez/storage/Cargo.toml b/lez/storage/Cargo.toml index 8767b525..930de77c 100644 --- a/lez/storage/Cargo.toml +++ b/lez/storage/Cargo.toml @@ -15,6 +15,7 @@ thiserror.workspace = true borsh.workspace = true rocksdb.workspace = true tempfile.workspace = true +zstd.workspace = true [dev-dependencies] programs.workspace = true diff --git a/lez/storage/src/error.rs b/lez/storage/src/error.rs index 3056e09b..069a95d8 100644 --- a/lez/storage/src/error.rs +++ b/lez/storage/src/error.rs @@ -12,6 +12,12 @@ pub enum DbError { error: borsh::io::Error, additional_info: Option, }, + #[error("Compression error: {}", additional_info.as_deref().unwrap_or("No additional info"))] + CompressionError { + #[source] + error: std::io::Error, + additional_info: Option, + }, #[error("Logic Error: {additional_info}")] DbInteractionError { additional_info: String }, } @@ -33,6 +39,14 @@ impl DbError { } } + #[must_use] + pub const fn compression_error(err: std::io::Error, message: Option) -> Self { + Self::CompressionError { + error: err, + additional_info: message, + } + } + #[must_use] pub const fn db_interaction_error(message: String) -> Self { Self::DbInteractionError { diff --git a/lez/storage/src/sequencer/mod.rs b/lez/storage/src/sequencer/mod.rs index 13f0c378..1a3a1886 100644 --- a/lez/storage/src/sequencer/mod.rs +++ b/lez/storage/src/sequencer/mod.rs @@ -62,17 +62,27 @@ pub struct DbDump { } impl DbDump { - /// Serialize the dump to a borsh blob. + /// Serialize the dump to a zstd-compressed borsh blob. pub fn to_bytes(&self) -> DbResult> { - borsh::to_vec(self).map_err(|err| { + /// zstd compression level for [`DbDump::to_bytes`]. Level 19 keeps the committed fixture + /// small without a meaningful decompression cost. + const DUMP_ZSTD_LEVEL: i32 = 19; + + let borsh = borsh::to_vec(self).map_err(|err| { DbError::borsh_cast_message(err, Some("Failed to serialize DbDump".to_owned())) + })?; + zstd::encode_all(borsh.as_slice(), DUMP_ZSTD_LEVEL).map_err(|err| { + DbError::compression_error(err, Some("Failed to compress DbDump".to_owned())) }) } /// Deserialize a dump produced by [`Self::to_bytes`]. pub fn from_bytes(bytes: &[u8]) -> DbResult { - borsh::from_slice(bytes).map_err(|err| { - DbError::borsh_cast_message(err, Some("Failed to deserialize DbDump".to_owned())) + let borsh = zstd::decode_all(bytes).map_err(|err| { + DbError::db_interaction_error(format!("Failed to decompress DbDump: {err}")) + })?; + borsh::from_slice(&borsh).map_err(|err| { + DbError::compression_error(err, Some("Failed to deserialize DbDump".to_owned())) }) } } diff --git a/test_fixtures/fixtures/prebuilt_sequencer_db.dump b/test_fixtures/fixtures/prebuilt_sequencer_db.dump index e07ec265..2528b798 100644 Binary files a/test_fixtures/fixtures/prebuilt_sequencer_db.dump and b/test_fixtures/fixtures/prebuilt_sequencer_db.dump differ