Skip to content

Commit

Permalink
feat: tx and receipt compression utils for no-std config (#11112)
Browse files Browse the repository at this point in the history
  • Loading branch information
nadtech-hub authored Sep 26, 2024
1 parent d46f762 commit 6d0159e
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 16 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 29 additions & 2 deletions crates/primitives/src/compression/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use alloc::vec::Vec;
use core::cell::RefCell;
use std::thread_local;
use zstd::bulk::{Compressor, Decompressor};

/// Compression/Decompression dictionary for `Receipt`.
Expand All @@ -10,7 +9,8 @@ pub static TRANSACTION_DICTIONARY: &[u8] = include_bytes!("./transaction_diction

// We use `thread_local` compressors and decompressors because dictionaries can be quite big, and
// zstd-rs recommends to use one context/compressor per thread
thread_local! {
#[cfg(feature = "std")]
std::thread_local! {
/// Thread Transaction compressor.
pub static TRANSACTION_COMPRESSOR: RefCell<Compressor<'static>> = RefCell::new(
Compressor::with_dictionary(0, TRANSACTION_DICTIONARY)
Expand Down Expand Up @@ -38,6 +38,33 @@ thread_local! {
));
}

/// Fn creates tx [`Compressor`]
pub fn create_tx_compressor() -> Compressor<'static> {
Compressor::with_dictionary(0, RECEIPT_DICTIONARY).expect("Failed to instantiate tx compressor")
}

/// Fn creates tx [`Decompressor`]
pub fn create_tx_decompressor() -> ReusableDecompressor {
ReusableDecompressor::new(
Decompressor::with_dictionary(TRANSACTION_DICTIONARY)
.expect("Failed to instantiate tx decompressor"),
)
}

/// Fn creates receipt [`Compressor`]
pub fn create_receipt_compressor() -> Compressor<'static> {
Compressor::with_dictionary(0, RECEIPT_DICTIONARY)
.expect("Failed to instantiate receipt compressor")
}

/// Fn creates receipt [`Decompressor`]
pub fn create_receipt_decompressor() -> ReusableDecompressor {
ReusableDecompressor::new(
Decompressor::with_dictionary(RECEIPT_DICTIONARY)
.expect("Failed to instantiate receipt decompressor"),
)
}

/// Reusable decompressor that uses its own internal buffer.
#[allow(missing_debug_implementations)]
pub struct ReusableDecompressor {
Expand Down
34 changes: 24 additions & 10 deletions crates/primitives/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -956,15 +956,20 @@ impl reth_codecs::Compact for TransactionSignedNoHash {
let zstd_bit = self.transaction.input().len() >= 32;

let tx_bits = if zstd_bit {
crate::compression::TRANSACTION_COMPRESSOR.with(|compressor| {
let mut compressor = compressor.borrow_mut();
let mut tmp = Vec::with_capacity(256);
let mut tmp = Vec::with_capacity(256);
if cfg!(feature = "std") {
crate::compression::TRANSACTION_COMPRESSOR.with(|compressor| {
let mut compressor = compressor.borrow_mut();
let tx_bits = self.transaction.to_compact(&mut tmp);
buf.put_slice(&compressor.compress(&tmp).expect("Failed to compress"));
tx_bits as u8
})
} else {
let mut compressor = crate::compression::create_tx_compressor();
let tx_bits = self.transaction.to_compact(&mut tmp);

buf.put_slice(&compressor.compress(&tmp).expect("Failed to compress"));

tx_bits as u8
})
}
} else {
self.transaction.to_compact(buf) as u8
};
Expand All @@ -984,17 +989,26 @@ impl reth_codecs::Compact for TransactionSignedNoHash {

let zstd_bit = bitflags >> 3;
let (transaction, buf) = if zstd_bit != 0 {
crate::compression::TRANSACTION_DECOMPRESSOR.with(|decompressor| {
let mut decompressor = decompressor.borrow_mut();
if cfg!(feature = "std") {
crate::compression::TRANSACTION_DECOMPRESSOR.with(|decompressor| {
let mut decompressor = decompressor.borrow_mut();

// TODO: enforce that zstd is only present at a "top" level type
// TODO: enforce that zstd is only present at a "top" level type

let transaction_type = (bitflags & 0b110) >> 1;
let (transaction, _) =
Transaction::from_compact(decompressor.decompress(buf), transaction_type);

(transaction, buf)
})
} else {
let mut decompressor = crate::compression::create_tx_decompressor();
let transaction_type = (bitflags & 0b110) >> 1;
let (transaction, _) =
Transaction::from_compact(decompressor.decompress(buf), transaction_type);

(transaction, buf)
})
}
} else {
let transaction_type = bitflags >> 1;
Transaction::from_compact(buf, transaction_type)
Expand Down

0 comments on commit 6d0159e

Please sign in to comment.