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// SpamFilterConfigSerializable moved to spam_filter module
121
122impl Default for UtxoCommitmentsConfig {
123    fn default() -> Self {
124        Self {
125            sync_mode: SyncMode::PeerConsensus,
126            verification_level: VerificationLevel::Standard,
127            consensus: ConsensusConfigSerializable {
128                min_peers: 5,
129                target_peers: 10,
130                consensus_threshold: 0.8,
131                max_peers_per_asn: 2,
132                safety_margin: 2016,
133                shuffle_peers: true,
134            },
135            spam_filter: crate::spam_filter::SpamFilterConfigSerializable::default(),
136            storage: StorageConfig::default(),
137        }
138    }
139}
140
141impl UtxoCommitmentsConfig {
142    /// Load configuration from JSON file
143    pub fn from_json_file(path: &std::path::Path) -> Result<Self, String> {
144        let content = std::fs::read_to_string(path)
145            .map_err(|e| format!("Failed to read config file: {e}"))?;
146
147        serde_json::from_str(&content).map_err(|e| format!("Failed to parse config JSON: {e}"))
148    }
149
150    /// Save configuration to JSON file
151    pub fn to_json_file(&self, path: &std::path::Path) -> Result<(), String> {
152        let content = serde_json::to_string_pretty(self)
153            .map_err(|e| format!("Failed to serialize config: {e}"))?;
154
155        std::fs::write(path, content).map_err(|e| format!("Failed to write config file: {e}"))
156    }
157
158    /// Create default configuration file template
159    pub fn create_default_config_file(path: &std::path::Path) -> Result<(), String> {
160        let default_config = Self::default();
161        default_config.to_json_file(path)
162    }
163
164    /// Convert to ConsensusConfig
165    #[cfg(feature = "utxo-commitments")]
166    pub fn to_consensus_config(&self) -> ConsensusConfig {
167        self.consensus.clone().into()
168    }
169
170    /// Convert to SpamFilterConfig
171    pub fn to_spam_filter_config(&self) -> SpamFilterConfig {
172        self.spam_filter.clone().into()
173    }
174
175    /// Validate configuration
176    pub fn validate(&self) -> Result<(), String> {
177        // Validate consensus config
178        if self.consensus.min_peers == 0 {
179            return Err("min_peers must be > 0".to_string());
180        }
181        if self.consensus.target_peers < self.consensus.min_peers {
182            return Err("target_peers must be >= min_peers".to_string());
183        }
184        if self.consensus.consensus_threshold < 0.0 || self.consensus.consensus_threshold > 1.0 {
185            return Err("consensus_threshold must be between 0.0 and 1.0".to_string());
186        }
187        if self.consensus.max_peers_per_asn == 0 {
188            return Err("max_peers_per_asn must be > 0".to_string());
189        }
190
191        // Validate spam filter config
192        if self.spam_filter.dust_threshold < 0 {
193            return Err("dust_threshold must be >= 0".to_string());
194        }
195        if self.spam_filter.min_output_value < 0 {
196            return Err("min_output_value must be >= 0".to_string());
197        }
198
199        Ok(())
200    }
201}