// Fluid Block Model (FBM) // 流体区块模型 - 动态调整区块大小和出块频率 use serde::{Deserialize, Serialize}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; /// 流体区块配置 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FluidBlockConfig { /// 最小出块间隔(毫秒) pub min_block_interval_ms: u64, /// 初始软上限(字节) pub initial_soft_limit: usize, /// 最大软上限(字节) pub max_soft_limit: usize, /// 软上限调整阈值(百分比,0-100) pub adjustment_threshold: u8, /// 软上限增长率(百分比,0-100) pub growth_rate: u8, /// 软上限收缩率(百分比,0-100) pub shrink_rate: u8, /// 调整窗口大小(区块数量) pub adjustment_window: usize, } impl Default for FluidBlockConfig { fn default() -> Self { Self { min_block_interval_ms: 100, // 0.1秒 initial_soft_limit: 1_000_000, // 1MB max_soft_limit: 10_000_000, // 10MB adjustment_threshold: 90, // 90% growth_rate: 10, // 增长10% shrink_rate: 5, // 收缩5% adjustment_window: 10, // 最近10个区块 } } } /// 区块大小统计 #[derive(Debug, Clone)] struct BlockSizeStats { /// 区块大小(字节) size: usize, /// 区块时间戳 timestamp: u64, } /// 流体区块模型管理器 pub struct FluidBlockModel { /// 配置 config: FluidBlockConfig, /// 当前软上限 current_soft_limit: usize, /// 最近的区块统计 recent_blocks: Vec, /// 上一个区块的时间戳 last_block_time: u64, /// 待打包的交易总大小 pending_tx_size: usize, } impl FluidBlockModel { /// 创建新的流体区块模型 pub fn new(config: FluidBlockConfig) -> Self { Self { current_soft_limit: config.initial_soft_limit, config, recent_blocks: Vec::new(), last_block_time: 0, pending_tx_size: 0, } } /// 使用默认配置创建 pub fn with_defaults() -> Self { Self::new(FluidBlockConfig::default()) } /// 检查是否可以出块 pub fn can_produce_block(&self) -> bool { let now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_millis() as u64; // 检查是否满足最小间隔 let interval_ok = if self.last_block_time == 0 { true } else { now - self.last_block_time >= self.config.min_block_interval_ms }; // 检查是否有待打包的交易 let has_pending = self.pending_tx_size > 0; interval_ok && has_pending } /// 获取当前软上限 pub fn get_soft_limit(&self) -> usize { self.current_soft_limit } /// 更新待打包交易大小 pub fn update_pending_size(&mut self, size: usize) { self.pending_tx_size = size; } /// 记录新产生的区块 pub fn record_block(&mut self, block_size: usize) { let now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_millis() as u64; // 记录区块统计 self.recent_blocks.push(BlockSizeStats { size: block_size, timestamp: now, }); // 只保留最近的N个区块 if self.recent_blocks.len() > self.config.adjustment_window { self.recent_blocks.remove(0); } // 更新最后区块时间 self.last_block_time = now; // 重置待打包交易大小 self.pending_tx_size = 0; // 触发软上限调整 self.adjust_soft_limit(); } /// 调整软上限 fn adjust_soft_limit(&mut self) { if self.recent_blocks.len() < self.config.adjustment_window { return; // 数据不足,不调整 } // 计算平均区块大小 let total_size: usize = self.recent_blocks.iter().map(|b| b.size).sum(); let avg_size = total_size / self.recent_blocks.len(); // 计算使用率 let usage_rate = (avg_size * 100) / self.current_soft_limit; // 根据使用率调整软上限 if usage_rate >= self.config.adjustment_threshold as usize { // 使用率高,增加软上限 let increase = (self.current_soft_limit * self.config.growth_rate as usize) / 100; self.current_soft_limit = (self.current_soft_limit + increase) .min(self.config.max_soft_limit); } else if usage_rate < 50 { // 使用率低,减少软上限 let decrease = (self.current_soft_limit * self.config.shrink_rate as usize) / 100; self.current_soft_limit = (self.current_soft_limit - decrease) .max(self.config.initial_soft_limit); } } /// 获取建议的出块时间 pub fn get_suggested_block_time(&self) -> Duration { Duration::from_millis(self.config.min_block_interval_ms) } /// 获取统计信息 pub fn get_stats(&self) -> FluidBlockStats { let avg_size = if !self.recent_blocks.is_empty() { let total: usize = self.recent_blocks.iter().map(|b| b.size).sum(); total / self.recent_blocks.len() } else { 0 }; let avg_interval = if self.recent_blocks.len() > 1 { let first = self.recent_blocks.first().unwrap().timestamp; let last = self.recent_blocks.last().unwrap().timestamp; let total_time = last - first; total_time / (self.recent_blocks.len() - 1) as u64 } else { 0 }; FluidBlockStats { current_soft_limit: self.current_soft_limit, avg_block_size: avg_size, avg_block_interval_ms: avg_interval, recent_blocks_count: self.recent_blocks.len(), pending_tx_size: self.pending_tx_size, } } /// 重置统计 pub fn reset(&mut self) { self.recent_blocks.clear(); self.current_soft_limit = self.config.initial_soft_limit; self.last_block_time = 0; self.pending_tx_size = 0; } } /// 流体区块统计信息 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FluidBlockStats { /// 当前软上限(字节) pub current_soft_limit: usize, /// 平均区块大小(字节) pub avg_block_size: usize, /// 平均出块间隔(毫秒) pub avg_block_interval_ms: u64, /// 最近区块数量 pub recent_blocks_count: usize, /// 待打包交易大小(字节) pub pending_tx_size: usize, } #[cfg(test)] mod tests { use super::*; use std::thread; #[test] fn test_fbm_creation() { let fbm = FluidBlockModel::with_defaults(); assert_eq!(fbm.get_soft_limit(), 1_000_000); } #[test] fn test_can_produce_block() { let mut fbm = FluidBlockModel::with_defaults(); // 初始状态,没有待打包交易,不能出块 assert!(!fbm.can_produce_block()); // 添加待打包交易 fbm.update_pending_size(1000); // 现在应该可以出块 assert!(fbm.can_produce_block()); } #[test] fn test_min_block_interval() { let mut config = FluidBlockConfig::default(); config.min_block_interval_ms = 100; let mut fbm = FluidBlockModel::new(config); fbm.update_pending_size(1000); assert!(fbm.can_produce_block()); // 记录一个区块 fbm.record_block(1000); // 立即检查,应该不能出块(未满足最小间隔) fbm.update_pending_size(1000); assert!(!fbm.can_produce_block()); // 等待最小间隔 thread::sleep(Duration::from_millis(150)); assert!(fbm.can_produce_block()); } #[test] fn test_soft_limit_increase() { let mut config = FluidBlockConfig::default(); config.adjustment_window = 3; config.adjustment_threshold = 90; config.growth_rate = 10; let mut fbm = FluidBlockModel::new(config); let initial_limit = fbm.get_soft_limit(); // 记录多个接近软上限的区块 for _ in 0..3 { thread::sleep(Duration::from_millis(150)); fbm.update_pending_size(950_000); fbm.record_block(950_000); // 95%使用率 } // 软上限应该增加 assert!(fbm.get_soft_limit() > initial_limit); } #[test] fn test_soft_limit_decrease() { // 测试软上限不会低于initial_soft_limit let mut config = FluidBlockConfig::default(); config.adjustment_window = 3; config.shrink_rate = 10; let mut fbm = FluidBlockModel::new(config); let initial_limit = fbm.get_soft_limit(); // 记录多个小区块 for _ in 0..5 { thread::sleep(Duration::from_millis(150)); fbm.update_pending_size(100_000); fbm.record_block(100_000); } // 软上限不应该低于initial_soft_limit assert!(fbm.get_soft_limit() >= initial_limit); } #[test] fn test_soft_limit_bounds() { let mut config = FluidBlockConfig::default(); config.adjustment_window = 3; config.initial_soft_limit = 1_000_000; config.max_soft_limit = 2_000_000; config.growth_rate = 50; // 50%增长 let mut fbm = FluidBlockModel::new(config); // 记录多个大区块,触发多次增长 for _ in 0..10 { thread::sleep(Duration::from_millis(150)); fbm.update_pending_size(950_000); fbm.record_block(950_000); } // 软上限不应超过最大值 assert!(fbm.get_soft_limit() <= 2_000_000); } #[test] fn test_stats() { let mut fbm = FluidBlockModel::with_defaults(); // 记录一些区块 for i in 1..=5 { thread::sleep(Duration::from_millis(150)); fbm.update_pending_size(i * 100_000); fbm.record_block(i * 100_000); } let stats = fbm.get_stats(); assert_eq!(stats.recent_blocks_count, 5); assert!(stats.avg_block_size > 0); assert!(stats.avg_block_interval_ms > 0); } #[test] fn test_reset() { let mut fbm = FluidBlockModel::with_defaults(); fbm.update_pending_size(1000); fbm.record_block(1000); fbm.reset(); let stats = fbm.get_stats(); assert_eq!(stats.recent_blocks_count, 0); assert_eq!(stats.pending_tx_size, 0); assert_eq!(fbm.get_soft_limit(), 1_000_000); } #[test] fn test_pending_size_update() { let mut fbm = FluidBlockModel::with_defaults(); fbm.update_pending_size(5000); let stats = fbm.get_stats(); assert_eq!(stats.pending_tx_size, 5000); // 记录区块后应该重置 fbm.record_block(5000); let stats = fbm.get_stats(); assert_eq!(stats.pending_tx_size, 0); } } // === 流体区块模型高级功能 === /// 网络负载级别 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum NetworkLoad { /// 空闲(<30%) Idle, /// 正常(30-70%) Normal, /// 繁忙(70-90%) Busy, /// 拥塞(>90%) Congested, } /// 交易优先级 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub enum TransactionPriority { /// 低优先级 Low = 1, /// 正常优先级 Normal = 2, /// 高优先级 High = 3, /// 紧急优先级 Urgent = 4, } /// 拥塞控制策略 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CongestionControl { /// 拥塞阈值(百分比,0-100) pub congestion_threshold: u8, /// 拥塞时的最小Gas价格倍数 pub min_gas_multiplier: f64, /// 是否启用优先级队列 pub enable_priority_queue: bool, /// 最大待处理交易数 pub max_pending_txs: usize, } impl Default for CongestionControl { fn default() -> Self { Self { congestion_threshold: 85, min_gas_multiplier: 1.5, enable_priority_queue: true, max_pending_txs: 10000, } } } /// 增强的流体区块模型 pub struct EnhancedFluidBlockModel { /// 基础流体区块模型 base: FluidBlockModel, /// 拥塞控制配置 congestion_control: CongestionControl, /// 当前网络负载 current_load: NetworkLoad, /// 待处理交易数量(按优先级) pending_txs_by_priority: [usize; 4], // Low, Normal, High, Urgent } impl EnhancedFluidBlockModel { /// 创建增强的流体区块模型 pub fn new(config: FluidBlockConfig, congestion_control: CongestionControl) -> Self { Self { base: FluidBlockModel::new(config), congestion_control, current_load: NetworkLoad::Idle, pending_txs_by_priority: [0; 4], } } /// 使用默认配置创建 pub fn with_defaults() -> Self { Self::new(FluidBlockConfig::default(), CongestionControl::default()) } /// 计算当前网络负载 pub fn calculate_network_load(&self) -> NetworkLoad { let stats = self.base.get_stats(); let usage_rate = if stats.current_soft_limit > 0 { (stats.avg_block_size * 100) / stats.current_soft_limit } else { 0 }; match usage_rate { 0..=30 => NetworkLoad::Idle, 31..=70 => NetworkLoad::Normal, 71..=90 => NetworkLoad::Busy, _ => NetworkLoad::Congested, } } /// 更新网络负载 pub fn update_network_load(&mut self) { self.current_load = self.calculate_network_load(); } /// 获取当前网络负载 pub fn get_network_load(&self) -> NetworkLoad { self.current_load } /// 添加待处理交易 pub fn add_pending_tx(&mut self, priority: TransactionPriority, size: usize) -> Result<(), String> { // 检查是否超过最大待处理交易数 let total_pending: usize = self.pending_txs_by_priority.iter().sum(); if total_pending >= self.congestion_control.max_pending_txs { return Err("达到最大待处理交易数".to_string()); } // 根据优先级添加 let priority_index = priority as usize - 1; self.pending_txs_by_priority[priority_index] += 1; // 更新基础模型的待处理大小 let current_pending = self.base.get_stats().pending_tx_size; self.base.update_pending_size(current_pending + size); Ok(()) } /// 获取建议的Gas价格倍数 pub fn get_suggested_gas_multiplier(&self) -> f64 { match self.current_load { NetworkLoad::Idle => 1.0, NetworkLoad::Normal => 1.0, NetworkLoad::Busy => 1.2, NetworkLoad::Congested => self.congestion_control.min_gas_multiplier, } } /// 获取建议的出块策略 pub fn get_block_production_strategy(&self) -> BlockProductionStrategy { match self.current_load { NetworkLoad::Idle => BlockProductionStrategy::Conservative, NetworkLoad::Normal => BlockProductionStrategy::Normal, NetworkLoad::Busy => BlockProductionStrategy::Aggressive, NetworkLoad::Congested => BlockProductionStrategy::Emergency, } } /// 检查是否应该出块(增强版) pub fn should_produce_block(&self) -> bool { // 基础检查 if !self.base.can_produce_block() { return false; } // 根据网络负载和优先级决定 match self.current_load { NetworkLoad::Idle | NetworkLoad::Normal => { // 正常情况,按基础模型决定 true } NetworkLoad::Busy => { // 繁忙时,优先处理高优先级交易 self.pending_txs_by_priority[2] > 0 || self.pending_txs_by_priority[3] > 0 } NetworkLoad::Congested => { // 拥塞时,只处理紧急交易 self.pending_txs_by_priority[3] > 0 } } } /// 获取下一批应该打包的交易优先级 pub fn get_next_batch_priority(&self) -> Vec { let mut priorities = Vec::new(); match self.current_load { NetworkLoad::Idle | NetworkLoad::Normal => { // 正常情况,按优先级顺序处理 if self.pending_txs_by_priority[3] > 0 { priorities.push(TransactionPriority::Urgent); } if self.pending_txs_by_priority[2] > 0 { priorities.push(TransactionPriority::High); } if self.pending_txs_by_priority[1] > 0 { priorities.push(TransactionPriority::Normal); } if self.pending_txs_by_priority[0] > 0 { priorities.push(TransactionPriority::Low); } } NetworkLoad::Busy => { // 繁忙时,只处理高优先级和紧急 if self.pending_txs_by_priority[3] > 0 { priorities.push(TransactionPriority::Urgent); } if self.pending_txs_by_priority[2] > 0 { priorities.push(TransactionPriority::High); } } NetworkLoad::Congested => { // 拥塞时,只处理紧急 if self.pending_txs_by_priority[3] > 0 { priorities.push(TransactionPriority::Urgent); } } } priorities } /// 记录区块生产(增强版) pub fn record_block_production(&mut self, block_size: usize, included_priorities: &[TransactionPriority]) { // 更新基础模型 self.base.record_block(block_size); // 减少已打包的交易数量 for priority in included_priorities { let priority_index = *priority as usize - 1; if self.pending_txs_by_priority[priority_index] > 0 { self.pending_txs_by_priority[priority_index] -= 1; } } // 更新网络负载 self.update_network_load(); } /// 获取增强统计信息 pub fn get_enhanced_stats(&self) -> EnhancedFluidBlockStats { let base_stats = self.base.get_stats(); EnhancedFluidBlockStats { base_stats, network_load: self.current_load, pending_low: self.pending_txs_by_priority[0], pending_normal: self.pending_txs_by_priority[1], pending_high: self.pending_txs_by_priority[2], pending_urgent: self.pending_txs_by_priority[3], suggested_gas_multiplier: self.get_suggested_gas_multiplier(), } } } /// 出块策略 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum BlockProductionStrategy { /// 保守策略(等待更多交易) Conservative, /// 正常策略 Normal, /// 激进策略(快速出块) Aggressive, /// 紧急策略(只处理紧急交易) Emergency, } /// 增强的流体区块统计信息 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EnhancedFluidBlockStats { /// 基础统计 pub base_stats: FluidBlockStats, /// 当前网络负载 pub network_load: NetworkLoad, /// 低优先级待处理交易数 pub pending_low: usize, /// 正常优先级待处理交易数 pub pending_normal: usize, /// 高优先级待处理交易数 pub pending_high: usize, /// 紧急优先级待处理交易数 pub pending_urgent: usize, /// 建议的Gas价格倍数 pub suggested_gas_multiplier: f64, } #[cfg(test)] mod enhanced_tests { use super::*; use std::thread; #[test] fn test_network_load_calculation() { let mut efbm = EnhancedFluidBlockModel::with_defaults(); // 初始状态应该是空闲 efbm.update_network_load(); assert_eq!(efbm.get_network_load(), NetworkLoad::Idle); // 记录一些大区块,增加负载 for _ in 0..5 { thread::sleep(Duration::from_millis(150)); efbm.base.update_pending_size(800_000); efbm.base.record_block(800_000); } efbm.update_network_load(); // 80%使用率应该是繁忙 assert_eq!(efbm.get_network_load(), NetworkLoad::Busy); } #[test] fn test_priority_queue() { let mut efbm = EnhancedFluidBlockModel::with_defaults(); // 添加不同优先级的交易 assert!(efbm.add_pending_tx(TransactionPriority::Low, 1000).is_ok()); assert!(efbm.add_pending_tx(TransactionPriority::Normal, 1000).is_ok()); assert!(efbm.add_pending_tx(TransactionPriority::High, 1000).is_ok()); assert!(efbm.add_pending_tx(TransactionPriority::Urgent, 1000).is_ok()); let stats = efbm.get_enhanced_stats(); assert_eq!(stats.pending_low, 1); assert_eq!(stats.pending_normal, 1); assert_eq!(stats.pending_high, 1); assert_eq!(stats.pending_urgent, 1); } #[test] fn test_congestion_control() { let mut efbm = EnhancedFluidBlockModel::with_defaults(); // 模拟拥塞状态 for _ in 0..5 { thread::sleep(Duration::from_millis(150)); efbm.base.update_pending_size(950_000); efbm.base.record_block(950_000); } efbm.update_network_load(); // 拥塞时,Gas倍数应该增加 let multiplier = efbm.get_suggested_gas_multiplier(); assert!(multiplier > 1.0); // 拥塞时,只处理紧急交易 efbm.add_pending_tx(TransactionPriority::Low, 1000).ok(); efbm.add_pending_tx(TransactionPriority::Urgent, 1000).ok(); let priorities = efbm.get_next_batch_priority(); assert_eq!(priorities.len(), 1); assert_eq!(priorities[0], TransactionPriority::Urgent); } #[test] fn test_block_production_strategy() { let mut efbm = EnhancedFluidBlockModel::with_defaults(); // 空闲状态 efbm.update_network_load(); assert_eq!(efbm.get_block_production_strategy(), BlockProductionStrategy::Conservative); // 记录一些区块,增加负载 for _ in 0..5 { thread::sleep(Duration::from_millis(150)); efbm.base.update_pending_size(500_000); efbm.base.record_block(500_000); } efbm.update_network_load(); assert_eq!(efbm.get_block_production_strategy(), BlockProductionStrategy::Normal); } #[test] fn test_max_pending_txs() { let mut config = FluidBlockConfig::default(); let mut congestion_control = CongestionControl::default(); congestion_control.max_pending_txs = 5; let mut efbm = EnhancedFluidBlockModel::new(config, congestion_control); // 添加5个交易应该成功 for _ in 0..5 { assert!(efbm.add_pending_tx(TransactionPriority::Normal, 1000).is_ok()); } // 第6个应该失败 assert!(efbm.add_pending_tx(TransactionPriority::Normal, 1000).is_err()); } }