use crate::core::traits::{CompressionStrategy, CompressionError, CompressionMetadata, CompressionStats};
use serde::{Deserialize, Serialize};
#[cfg(feature = "zstd")]
use std::io::{Read, Write};
#[cfg(feature = "solana")]
use solana_sdk::{pubkey::Pubkey, signature::Signature};
pub struct SolanaCompressor {
compression_level: i32,
preset: SolanaPreset,
dictionary: Option<Vec<u8>>,
stats: CompressionStats,
}
impl std::fmt::Debug for SolanaCompressor {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SolanaCompressor")
.field("compression_level", &self.compression_level)
.field("preset", &self.preset)
.field("dictionary_size", &self.dictionary.as_ref().map(|d| d.len()))
.field("stats", &self.stats)
.finish()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SolanaPreset {
Transactions,
Accounts,
Instructions,
Mixed,
MaxCompression,
FastCompression,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SolanaPatternType {
PublicKey,
Signature,
ProgramId,
Amount,
Blockhash,
InstructionData,
}
const SOLANA_DICTIONARY_PATTERNS: &[&str] = &[
"11111111111111111111111111111112", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM", "BPFLoaderUpgradeab1e11111111111111111111111", "Config1111111111111111111111111111111111111", "Vote111111111111111111111111111111111111111", "Stake11111111111111111111111111111111111111",
"00000000", "01000000", "02000000", "03000000",
"00e1f50500000000", "00ca9a3b00000000", "0010270000000000", "00e40b5402000000",
"0100", "0200", "0300", ];
impl SolanaCompressor {
pub fn new(preset: SolanaPreset) -> Self {
let compression_level = Self::preset_to_level(&preset);
let dictionary = Self::build_solana_dictionary();
Self {
compression_level,
preset,
dictionary: Some(dictionary),
stats: CompressionStats::default(),
}
}
fn preset_to_level(preset: &SolanaPreset) -> i32 {
match preset {
SolanaPreset::FastCompression => 3, SolanaPreset::Transactions => 3, SolanaPreset::Instructions => 6, SolanaPreset::Accounts => 6, SolanaPreset::Mixed => 6, SolanaPreset::MaxCompression => 19, }
}
fn build_solana_dictionary() -> Vec<u8> {
let mut dictionary_data = Vec::new();
for pattern in SOLANA_DICTIONARY_PATTERNS {
dictionary_data.extend_from_slice(pattern.as_bytes());
dictionary_data.push(0); }
dictionary_data.extend_from_slice(b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
dictionary_data
}
pub fn reset(&mut self) {
self.stats = CompressionStats::default();
}
#[cfg(feature = "solana")]
pub fn common_program_ids() -> Vec<Pubkey> {
vec![
solana_sdk::system_program::ID, spl_token::ID, spl_associated_token_account::ID, solana_sdk::sysvar::rent::ID, solana_sdk::sysvar::clock::ID, ]
}
#[cfg(feature = "solana")]
pub fn pre_populate_common_patterns(&mut self) -> Result<(), CompressionError> {
for program_id in Self::common_program_ids() {
self.add_pubkey_pattern(program_id)?;
}
for i in 0..=9 {
let amount = 10_u64.pow(i);
self.add_amount_pattern(amount)?;
}
Ok(())
}
#[cfg(feature = "solana")]
pub fn add_pubkey_pattern(&mut self, pubkey: Pubkey) -> Result<(), CompressionError> {
Ok(())
}
pub fn add_amount_pattern(&mut self, amount: u64) -> Result<(), CompressionError> {
Ok(())
}
pub fn optimize_for_transactions(&mut self) -> Result<(), CompressionError> {
Ok(())
}
pub fn solana_stats(&self) -> SolanaCompressionStats {
SolanaCompressionStats {
pubkey_patterns: 0,
signature_patterns: 0,
amount_patterns: 0,
total_solana_bytes_saved: 0,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SolanaCompressionStats {
pub signature_patterns: usize,
pub pubkey_patterns: usize,
pub amount_patterns: usize,
pub total_solana_bytes_saved: u64,
}
impl CompressionStrategy for SolanaCompressor {
type Error = CompressionError;
fn compress(&mut self, data: &[u8]) -> Result<Vec<u8>, Self::Error> {
if data.is_empty() {
return Ok(Vec::new());
}
let _start_time = std::time::Instant::now();
let compressed: Vec<u8> = match &self.dictionary {
Some(dict) => {
#[cfg(feature = "zstd")]
{
let mut encoder = zstd::stream::write::Encoder::with_dictionary(Vec::new(), self.compression_level, dict)
.map_err(|e| CompressionError::Internal {
message: format!("Failed to create zstd encoder with dictionary: {}", e),
})?;
encoder.write_all(data)
.map_err(|e| CompressionError::Internal {
message: format!("Failed to write data to zstd encoder: {}", e),
})?;
encoder.finish()
.map_err(|e| CompressionError::Internal {
message: format!("Failed to finish zstd compression: {}", e),
})?
}
#[cfg(not(feature = "zstd"))]
{
return Err(CompressionError::Internal {
message: "zstd feature not enabled".to_string(),
});
}
}
None => {
#[cfg(feature = "zstd")]
{
zstd::bulk::compress(data, self.compression_level)
.map_err(|e| CompressionError::Internal {
message: format!("zstd compression failed: {}", e),
})?
}
#[cfg(not(feature = "zstd"))]
{
return Err(CompressionError::Internal {
message: "zstd feature not enabled".to_string(),
});
}
}
};
self.stats.compressions += 1;
self.stats.total_input_bytes += data.len() as u64;
self.stats.total_output_bytes += compressed.len() as u64;
let ratio = data.len() as f64 / compressed.len() as f64;
if ratio > self.stats.best_ratio {
self.stats.best_ratio = ratio;
}
Ok(compressed)
}
fn decompress(&self, data: &[u8]) -> Result<Vec<u8>, Self::Error> {
if data.is_empty() {
return Ok(Vec::new());
}
let _start_time = std::time::Instant::now();
let decompressed: Vec<u8> = match &self.dictionary {
Some(dict) => {
#[cfg(feature = "zstd")]
{
let mut decoder = zstd::stream::read::Decoder::with_dictionary(data, dict)
.map_err(|e| CompressionError::Internal {
message: format!("Failed to create zstd decoder with dictionary: {}", e),
})?;
let mut decompressed = Vec::new();
decoder.read_to_end(&mut decompressed)
.map_err(|e| CompressionError::Internal {
message: format!("Failed to decompress with zstd: {}", e),
})?;
decompressed
}
#[cfg(not(feature = "zstd"))]
{
return Err(CompressionError::Internal {
message: "zstd feature not enabled".to_string(),
});
}
}
None => {
#[cfg(feature = "zstd")]
{
zstd::bulk::decompress(data, 1024 * 1024) .map_err(|e| CompressionError::Internal {
message: format!("zstd decompression failed: {}", e),
})?
}
#[cfg(not(feature = "zstd"))]
{
return Err(CompressionError::Internal {
message: "zstd feature not enabled".to_string(),
});
}
}
};
Ok(decompressed)
}
fn metadata(&self) -> CompressionMetadata {
CompressionMetadata {
name: "Solana Zstd Compressor".to_string(),
description: "Solana-optimized compression using Zstandard with custom dictionaries".to_string(),
version: "2.0.0".to_string(),
domains: vec!["Solana".to_string(), "Blockchain".to_string()],
deterministic: true,
memory_usage: (self.compression_level * 1024 * 1024) as usize, }
}
fn stats(&self) -> CompressionStats {
self.stats.clone()
}
fn reset(&mut self) {
self.stats = CompressionStats::default();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_solana_compressor_creation() {
let compressor = SolanaCompressor::new(SolanaPreset::Mixed);
let metadata = compressor.metadata();
assert_eq!(metadata.name, "Solana Zstd Compressor");
}
#[test]
fn test_transaction_preset() {
let compressor = SolanaCompressor::new(SolanaPreset::Transactions);
let stats = compressor.stats();
assert_eq!(stats.compressions, 0);
}
#[test]
fn test_zstd_compression_with_solana_patterns() {
let mut compressor = SolanaCompressor::new(SolanaPreset::Transactions);
let mut test_data = Vec::new();
for _ in 0..20 {
test_data.extend_from_slice("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA".as_bytes()); test_data.extend_from_slice("11111111111111111111111111111112".as_bytes()); }
println!("Original size: {} bytes", test_data.len());
let compressed = compressor.compress(&test_data).expect("Compression should work");
println!("Compressed size: {} bytes", compressed.len());
let decompressed = (&compressor as &dyn CompressionStrategy<Error = _>).decompress(&compressed)
.expect("Decompression should work");
assert_eq!(test_data, decompressed, "zstd must provide perfect data integrity");
let ratio = test_data.len() as f64 / compressed.len() as f64;
println!("Compression ratio: {:.2}:1", ratio);
assert!(ratio > 10.0, "Should achieve excellent compression on Solana patterns, got {:.2}:1", ratio);
let stats = compressor.stats();
assert_eq!(stats.compressions, 1);
assert!(stats.best_ratio > 10.0);
}
#[test]
fn test_preset_configurations() {
let presets = vec![
SolanaPreset::Transactions,
SolanaPreset::Accounts,
SolanaPreset::Instructions,
SolanaPreset::Mixed,
SolanaPreset::MaxCompression,
SolanaPreset::FastCompression,
];
for preset in presets {
let compressor = SolanaCompressor::new(preset);
let metadata = compressor.metadata();
assert_eq!(metadata.name, "Solana Zstd Compressor");
}
}
}