///! 状态分片优化模块 ///! ///! 优化分片状态存储和访问性能 ///! ///! **NAC原生设计原则**: ///! - 使用Asset(资产),不是Token ///! - 使用Certificate(证书),不是Contract ///! - 使用SHA3-384哈希,不是SHA256/Keccak256 ///! - 通过CBPP共识协调 use crate::primitives::{Address, Hash}; use std::collections::HashMap; use serde::{Deserialize, Serialize}; /// 状态分片优化器 #[derive(Debug, Clone)] /// StateShardOptimizer pub struct StateShardOptimizer { /// 分片ID shard_id: u64, /// 状态缓存 state_cache: HashMap, /// 热点账户追踪 hot_accounts: HashMap, /// 冷数据归档阈值(秒) cold_threshold: u64, /// 缓存大小限制(字节) max_cache_size: u64, /// 当前缓存大小 current_cache_size: u64, /// 优化统计 stats: OptimizationStats, } /// 状态条目 #[derive(Debug, Clone, Serialize, Deserialize)] /// StateEntry pub struct StateEntry { /// 状态键 pub key: Hash, /// 状态值 pub value: Vec, /// 最后访问时间 pub last_access: u64, /// 访问次数 pub access_count: u64, /// 是否为热点数据 pub is_hot: bool, /// 数据大小(字节) pub size: u64, } impl StateEntry { /// 创建新的状态条目 pub fn new(key: Hash, value: Vec, timestamp: u64) -> Self { let size = value.len() as u64; Self { key, value, last_access: timestamp, access_count: 1, is_hot: false, size, } } /// 更新访问信息 pub fn update_access(&mut self, timestamp: u64) { self.last_access = timestamp; self.access_count += 1; // 访问次数超过阈值标记为热点 if self.access_count > 100 { self.is_hot = true; } } /// 检查是否为冷数据 pub fn is_cold(&self, current_time: u64, threshold: u64) -> bool { current_time - self.last_access > threshold } } /// 热点账户统计 #[derive(Debug, Clone, Serialize, Deserialize)] /// HotAccountStats pub struct HotAccountStats { /// 账户地址 pub address: Address, /// 读取次数 pub read_count: u64, /// 写入次数 pub write_count: u64, /// 最后活动时间 pub last_activity: u64, /// 平均交易大小 pub avg_tx_size: u64, /// 是否为高频账户 pub is_high_frequency: bool, } impl HotAccountStats { /// 创建新的热点账户统计 pub fn new(address: Address, timestamp: u64) -> Self { Self { address, read_count: 0, write_count: 0, last_activity: timestamp, avg_tx_size: 0, is_high_frequency: false, } } /// 记录读取操作 pub fn record_read(&mut self, timestamp: u64) { self.read_count += 1; self.last_activity = timestamp; self.update_frequency(); } /// 记录写入操作 pub fn record_write(&mut self, timestamp: u64, tx_size: u64) { self.write_count += 1; self.last_activity = timestamp; // 更新平均交易大小 let total_count = self.read_count + self.write_count; self.avg_tx_size = (self.avg_tx_size * (total_count - 1) + tx_size) / total_count; self.update_frequency(); } /// 更新频率标记 fn update_frequency(&mut self) { // 读写总次数超过1000标记为高频 if self.read_count + self.write_count > 1000 { self.is_high_frequency = true; } } } /// 优化统计 #[derive(Debug, Clone, Serialize, Deserialize, Default)] /// OptimizationStats pub struct OptimizationStats { /// 缓存命中次数 pub cache_hits: u64, /// 缓存未命中次数 pub cache_misses: u64, /// 冷数据归档次数 pub cold_data_archived: u64, /// 热点数据提升次数 pub hot_data_promoted: u64, /// 缓存驱逐次数 pub cache_evictions: u64, /// 总状态访问次数 pub total_accesses: u64, } impl OptimizationStats { /// 计算缓存命中率 pub fn cache_hit_rate(&self) -> f64 { if self.total_accesses == 0 { return 0.0; } self.cache_hits as f64 / self.total_accesses as f64 } } impl StateShardOptimizer { /// 创建新的状态分片优化器 pub fn new(shard_id: u64, cold_threshold: u64, max_cache_size: u64) -> Self { Self { shard_id, state_cache: HashMap::new(), hot_accounts: HashMap::new(), cold_threshold, max_cache_size, current_cache_size: 0, stats: OptimizationStats::default(), } } /// 读取状态 pub fn read_state(&mut self, key: &Hash, current_time: u64) -> Option> { self.stats.total_accesses += 1; if let Some(entry) = self.state_cache.get_mut(key) { // 缓存命中 self.stats.cache_hits += 1; entry.update_access(current_time); Some(entry.value.clone()) } else { // 缓存未命中 self.stats.cache_misses += 1; None } } /// 写入状态 pub fn write_state(&mut self, key: Hash, value: Vec, current_time: u64) -> Result<(), String> { let entry_size = value.len() as u64; // 检查缓存大小限制 if self.current_cache_size + entry_size > self.max_cache_size { // 驱逐冷数据 self.evict_cold_data(current_time)?; } // 创建或更新状态条目 if let Some(existing) = self.state_cache.get_mut(&key) { self.current_cache_size -= existing.size; existing.value = value; existing.size = entry_size; existing.update_access(current_time); self.current_cache_size += entry_size; } else { let entry = StateEntry::new(key.clone(), value, current_time); self.state_cache.insert(key, entry); self.current_cache_size += entry_size; } Ok(()) } /// 驱逐冷数据 pub fn evict_cold_data(&mut self, current_time: u64) -> Result<(), String> { let mut cold_keys = Vec::new(); // 查找冷数据 for (key, entry) in &self.state_cache { if entry.is_cold(current_time, self.cold_threshold) && !entry.is_hot { cold_keys.push(key.clone()); } } if cold_keys.is_empty() { return Err("No cold data to evict".to_string()); } // 驱逐冷数据 for key in cold_keys { if let Some(entry) = self.state_cache.remove(&key) { self.current_cache_size -= entry.size; self.stats.cache_evictions += 1; self.stats.cold_data_archived += 1; } } Ok(()) } /// 提升热点数据 pub fn promote_hot_data(&mut self, key: &Hash) -> Result<(), String> { if let Some(entry) = self.state_cache.get_mut(key) { if !entry.is_hot { entry.is_hot = true; self.stats.hot_data_promoted += 1; } Ok(()) } else { Err("State entry not found".to_string()) } } /// 记录账户活动 pub fn record_account_activity( &mut self, address: Address, is_write: bool, tx_size: u64, timestamp: u64, ) { let stats = self.hot_accounts .entry(address.clone()) .or_insert_with(|| HotAccountStats::new(address, timestamp)); if is_write { stats.record_write(timestamp, tx_size); } else { stats.record_read(timestamp); } } /// 获取热点账户列表 pub fn get_hot_accounts(&self) -> Vec
{ self.hot_accounts .values() .filter(|stats| stats.is_high_frequency) .map(|stats| stats.address.clone()) .collect() } /// 获取优化统计 pub fn get_stats(&self) -> OptimizationStats { self.stats.clone() } /// 获取缓存使用率 pub fn get_cache_usage(&self) -> f64 { if self.max_cache_size == 0 { return 0.0; } self.current_cache_size as f64 / self.max_cache_size as f64 } /// 清理过期数据 pub fn cleanup_expired(&mut self, current_time: u64) -> usize { let mut expired_keys = Vec::new(); // 查找过期数据(超过冷数据阈值的2倍) let expiry_threshold = self.cold_threshold * 2; for (key, entry) in &self.state_cache { if current_time - entry.last_access > expiry_threshold { expired_keys.push(key.clone()); } } let count = expired_keys.len(); // 删除过期数据 for key in expired_keys { if let Some(entry) = self.state_cache.remove(&key) { self.current_cache_size -= entry.size; } } count } /// 优化分片状态 pub fn optimize(&mut self, current_time: u64) -> Result { let initial_cache_size = self.current_cache_size; let initial_entry_count = self.state_cache.len(); // 1. 清理过期数据 let expired_count = self.cleanup_expired(current_time); // 2. 驱逐冷数据(如果缓存使用率超过80%) let evicted_count = if self.get_cache_usage() > 0.8 { let before = self.state_cache.len(); self.evict_cold_data(current_time)?; before - self.state_cache.len() } else { 0 }; // 3. 提升热点数据 let hot_keys: Vec = self.state_cache .iter() .filter(|(_, entry)| entry.access_count > 50 && !entry.is_hot) .map(|(key, _)| key.clone()) .collect(); for key in &hot_keys { let _ = self.promote_hot_data(key); } Ok(OptimizationReport { shard_id: self.shard_id, expired_count, evicted_count, promoted_count: hot_keys.len(), space_freed: initial_cache_size - self.current_cache_size, entries_before: initial_entry_count, entries_after: self.state_cache.len(), cache_hit_rate: self.stats.cache_hit_rate(), }) } } /// 优化报告 #[derive(Debug, Clone, Serialize, Deserialize)] /// OptimizationReport pub struct OptimizationReport { /// 分片ID pub shard_id: u64, /// 清理的过期数据数量 pub expired_count: usize, /// 驱逐的冷数据数量 pub evicted_count: usize, /// 提升的热点数据数量 pub promoted_count: usize, /// 释放的空间(字节) pub space_freed: u64, /// 优化前条目数 pub entries_before: usize, /// 优化后条目数 pub entries_after: usize, /// 缓存命中率 pub cache_hit_rate: f64, } #[cfg(test)] mod tests { use super::*; #[test] fn test_state_entry_creation() { let key = Hash::from_slice(&[1u8; 32]).unwrap(); let value = vec![1, 2, 3, 4]; let entry = StateEntry::new(key, value.clone(), 1000); assert_eq!(entry.value, value); assert_eq!(entry.last_access, 1000); assert_eq!(entry.access_count, 1); assert!(!entry.is_hot); assert_eq!(entry.size, 4); } #[test] fn test_state_entry_hot_promotion() { let key = Hash::from_slice(&[1u8; 32]).unwrap(); let value = vec![1, 2, 3]; let mut entry = StateEntry::new(key, value, 1000); // 访问101次应该变为热点 for i in 0..101 { entry.update_access(1000 + i); } assert!(entry.is_hot); assert_eq!(entry.access_count, 102); // 初始1次 + 101次 } #[test] fn test_state_entry_cold_detection() { let key = Hash::from_slice(&[1u8; 32]).unwrap(); let value = vec![1, 2, 3]; let entry = StateEntry::new(key, value, 1000); // 在阈值内不是冷数据 assert!(!entry.is_cold(1500, 1000)); // 超过阈值是冷数据 assert!(entry.is_cold(2001, 1000)); } #[test] fn test_optimizer_read_write() { let mut optimizer = StateShardOptimizer::new(1, 3600, 1024 * 1024); let key = Hash::from_slice(&[1u8; 32]).unwrap(); let value = vec![1, 2, 3, 4]; // 写入状态 assert!(optimizer.write_state(key.clone(), value.clone(), 1000).is_ok()); // 读取状态 let read_value = optimizer.read_state(&key, 1001); assert_eq!(read_value, Some(value)); // 验证统计 assert_eq!(optimizer.stats.cache_hits, 1); assert_eq!(optimizer.stats.total_accesses, 1); } #[test] fn test_optimizer_cache_miss() { let mut optimizer = StateShardOptimizer::new(1, 3600, 1024 * 1024); let key = Hash::from_slice(&[1u8; 32]).unwrap(); // 读取不存在的状态 let result = optimizer.read_state(&key, 1000); assert!(result.is_none()); // 验证统计 assert_eq!(optimizer.stats.cache_misses, 1); assert_eq!(optimizer.stats.total_accesses, 1); } #[test] fn test_optimizer_evict_cold_data() { let mut optimizer = StateShardOptimizer::new(1, 1000, 1024); // 写入一些数据 for i in 0..5 { let key = Hash::from_slice(&[i; 32]).unwrap(); let value = vec![i; 100]; optimizer.write_state(key, value, 1000 + i as u64).unwrap(); } // 等待一段时间后驱逐冷数据 assert!(optimizer.evict_cold_data(3000).is_ok()); // 验证统计 assert!(optimizer.stats.cold_data_archived > 0); } #[test] fn test_optimizer_hot_account_tracking() { let mut optimizer = StateShardOptimizer::new(1, 3600, 1024 * 1024); let address = Address::from_slice(&[1u8; 20]).unwrap(); // 记录大量活动 for i in 0..1001 { optimizer.record_account_activity(address.clone(), i % 2 == 0, 100, 1000 + i); } // 验证热点账户 let hot_accounts = optimizer.get_hot_accounts(); assert_eq!(hot_accounts.len(), 1); assert_eq!(hot_accounts[0], address); } #[test] fn test_optimizer_cache_usage() { let mut optimizer = StateShardOptimizer::new(1, 3600, 1000); // 写入500字节数据 let key = Hash::from_slice(&[1u8; 32]).unwrap(); let value = vec![1u8; 500]; optimizer.write_state(key, value, 1000).unwrap(); // 验证缓存使用率 assert_eq!(optimizer.get_cache_usage(), 0.5); } #[test] fn test_optimizer_cleanup_expired() { let mut optimizer = StateShardOptimizer::new(1, 1000, 1024 * 1024); // 写入一些数据 for i in 0..5 { let key = Hash::from_slice(&[i; 32]).unwrap(); let value = vec![i; 10]; optimizer.write_state(key, value, 1000).unwrap(); } // 清理过期数据(超过2000秒) let expired = optimizer.cleanup_expired(4000); assert_eq!(expired, 5); } #[test] fn test_optimizer_full_optimization() { let mut optimizer = StateShardOptimizer::new(1, 1000, 1024 * 1024); // 写入一些数据 for i in 0..10 { let key = Hash::from_slice(&[i; 32]).unwrap(); let value = vec![i; 100]; optimizer.write_state(key, value, 1000 + i as u64).unwrap(); } // 访问部分数据使其成为热点(但不超过100次,避免自动标记为hot) for i in 0..3 { let key = Hash::from_slice(&[i; 32]).unwrap(); for _ in 0..50 { optimizer.read_state(&key, 2000); } } // 执行优化 let report = optimizer.optimize(4000).unwrap(); assert_eq!(report.shard_id, 1); assert!(report.promoted_count > 0); assert!(report.cache_hit_rate > 0.0); } }