Skip to main content

blvm_protocol/utxo_commitments/
config.rs

1//! Configuration for UTXO Commitments Module
2//!
3//! Provides configuration management for:
4//! - Peer consensus thresholds
5//! - Spam filter settings
6//! - Sync mode selection
7//! - Verification levels
8
9use crate::spam_filter::SpamFilterConfig;
10use serde::{Deserialize, Serialize};
11
12#[cfg(feature = "utxo-commitments")]
13use crate::utxo_commitments::peer_consensus::ConsensusConfig;
14
15/// Sync mode selection
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
17pub enum SyncMode {
18    /// Use peer consensus for initial sync (fast, trusts N of M peers)
19    PeerConsensus,
20    /// Sync from genesis (slow, but no trust required)
21    Genesis,
22    /// Hybrid: Use peer consensus but verify from genesis in background
23    Hybrid,
24}
25
26/// Verification level
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
28pub enum VerificationLevel {
29    /// Minimal verification (peer consensus only)
30    Minimal,
31    /// Standard verification (peer consensus + PoW + supply checks)
32    Standard,
33    /// Paranoid verification (all checks + background genesis verification)
34    Paranoid,
35}
36
37/// Storage preferences for UTXO commitments
38#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
39pub struct StorageConfig {
40    /// Keep filtered blocks (for debugging/analysis)
41    pub keep_filtered_blocks: bool,
42    /// Keep spam summary statistics
43    pub keep_spam_summary: bool,
44    /// Keep full UTXO set history (for verification)
45    pub keep_utxo_history: bool,
46    /// Maximum age for filtered blocks (days)
47    pub filtered_blocks_max_age_days: u32,
48}
49
50impl Default for StorageConfig {
51    fn default() -> Self {
52        Self {
53            keep_filtered_blocks: false,
54            keep_spam_summary: true,
55            keep_utxo_history: false,
56            filtered_blocks_max_age_days: 30,
57        }
58    }
59}
60
61/// Complete configuration for UTXO commitments module
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
63pub struct UtxoCommitmentsConfig {
64    /// Sync mode
65    pub sync_mode: SyncMode,
66    /// Verification level
67    pub verification_level: VerificationLevel,
68    /// Peer consensus configuration
69    pub consensus: ConsensusConfigSerializable,
70    /// Spam filter configuration
71    pub spam_filter: crate::spam_filter::SpamFilterConfigSerializable,
72    /// Storage preferences
73    pub storage: StorageConfig,
74}
75
76/// Serializable version of ConsensusConfig
77#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
78pub struct ConsensusConfigSerializable {
79    pub min_peers: usize,
80    pub target_peers: usize,
81    pub consensus_threshold: f64,
82    pub max_peers_per_asn: usize,
83    pub safety_margin: u64,
84    #[serde(default = "default_shuffle_peers")]
85    pub shuffle_peers: bool,
86}
87
88fn default_shuffle_peers() -> bool {
89    true
90}
91
92#[cfg(feature = "utxo-commitments")]
93impl From<ConsensusConfigSerializable> for ConsensusConfig {
94    fn from(serializable: ConsensusConfigSerializable) -> Self {
95        ConsensusConfig {
96            min_peers: serializable.min_peers,
97            target_peers: serializable.target_peers,
98            consensus_threshold: serializable.consensus_threshold,
99            max_peers_per_asn: serializable.max_peers_per_asn,
100            safety_margin: serializable.safety_margin,
101            shuffle_peers: serializable.shuffle_peers,
102        }
103    }
104}
105
106#[cfg(feature = "utxo-commitments")]
107impl From<ConsensusConfig> for ConsensusConfigSerializable {
108    fn from(config: ConsensusConfig) -> Self {
109        ConsensusConfigSerializable {
110            min_peers: config.min_peers,
111            target_peers: config.target_peers,
112            consensus_threshold: config.consensus_threshold,
113            max_peers_per_asn: config.max_peers_per_asn,
114            safety_margin: config.safety_margin,
115            shuffle_peers: config.shuffle_peers,
116        }
117    }
118}
119
120/// Serializable version of SpamFilterConfig
121// SpamFilterConfigSerializable moved to spam_filter module
122
123impl Default for UtxoCommitmentsConfig {
124    fn default() -> Self {
125        Self {
126            sync_mode: SyncMode::PeerConsensus,
127            verification_level: VerificationLevel::Standard,
128            consensus: ConsensusConfigSerializable {
129                min_peers: 5,
130                target_peers: 10,
131                consensus_threshold: 0.8,
132                max_peers_per_asn: 2,
133                safety_margin: 2016,
134                shuffle_peers: true,
135            },
136            spam_filter: crate::spam_filter::SpamFilterConfigSerializable::default(),
137            storage: StorageConfig::default(),
138        }
139    }
140}
141
142impl UtxoCommitmentsConfig {
143    /// Load configuration from JSON file
144    pub fn from_json_file(path: &std::path::Path) -> Result<Self, String> {
145        let content = std::fs::read_to_string(path)
146            .map_err(|e| format!("Failed to read config file: {}", e))?;
147
148        serde_json::from_str(&content).map_err(|e| format!("Failed to parse config JSON: {}", e))
149    }
150
151    /// Save configuration to JSON file
152    pub fn to_json_file(&self, path: &std::path::Path) -> Result<(), String> {
153        let content = serde_json::to_string_pretty(self)
154            .map_err(|e| format!("Failed to serialize config: {}", e))?;
155
156        std::fs::write(path, content).map_err(|e| format!("Failed to write config file: {}", e))
157    }
158
159    /// Create default configuration file template
160    pub fn create_default_config_file(path: &std::path::Path) -> Result<(), String> {
161        let default_config = Self::default();
162        default_config.to_json_file(path)
163    }
164
165    /// Convert to ConsensusConfig
166    #[cfg(feature = "utxo-commitments")]
167    pub fn to_consensus_config(&self) -> ConsensusConfig {
168        self.consensus.clone().into()
169    }
170
171    /// Convert to SpamFilterConfig
172    pub fn to_spam_filter_config(&self) -> SpamFilterConfig {
173        self.spam_filter.clone().into()
174    }
175
176    /// Validate configuration
177    pub fn validate(&self) -> Result<(), String> {
178        // Validate consensus config
179        if self.consensus.min_peers == 0 {
180            return Err("min_peers must be > 0".to_string());
181        }
182        if self.consensus.target_peers < self.consensus.min_peers {
183            return Err("target_peers must be >= min_peers".to_string());
184        }
185        if self.consensus.consensus_threshold < 0.0 || self.consensus.consensus_threshold > 1.0 {
186            return Err("consensus_threshold must be between 0.0 and 1.0".to_string());
187        }
188        if self.consensus.max_peers_per_asn == 0 {
189            return Err("max_peers_per_asn must be > 0".to_string());
190        }
191
192        // Validate spam filter config
193        if self.spam_filter.dust_threshold < 0 {
194            return Err("dust_threshold must be >= 0".to_string());
195        }
196        if self.spam_filter.min_output_value < 0 {
197            return Err("min_output_value must be >= 0".to_string());
198        }
199
200        Ok(())
201    }
202}