Skip to main content

blvm_protocol/
variants.rs

1//! Protocol variants implementation
2//!
3//! This module implements different Bitcoin protocol variants:
4//! - Mainnet: Production Bitcoin network
5//! - Testnet: Bitcoin test network
6//! - Regtest: Regression testing network
7
8use crate::ProtocolVersion;
9use serde::{Deserialize, Serialize};
10
11/// Protocol variant configuration
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
13pub struct ProtocolVariant {
14    pub version: ProtocolVersion,
15    pub name: String,
16    pub description: String,
17    pub is_production: bool,
18    pub supports_mining: bool,
19    pub supports_wallet: bool,
20}
21
22impl ProtocolVariant {
23    /// Get all available protocol variants
24    pub fn all_variants() -> Vec<Self> {
25        vec![
26            ProtocolVariant {
27                version: ProtocolVersion::BitcoinV1,
28                name: "Bitcoin Mainnet".to_string(),
29                description: "Production Bitcoin network with full consensus rules".to_string(),
30                is_production: true,
31                supports_mining: true,
32                supports_wallet: true,
33            },
34            ProtocolVariant {
35                version: ProtocolVersion::Testnet3,
36                name: "Bitcoin Testnet".to_string(),
37                description: "Bitcoin test network for development and testing".to_string(),
38                is_production: false,
39                supports_mining: true,
40                supports_wallet: true,
41            },
42            ProtocolVariant {
43                version: ProtocolVersion::Regtest,
44                name: "Bitcoin Regtest".to_string(),
45                description: "Regression testing network with configurable difficulty".to_string(),
46                is_production: false,
47                supports_mining: true,
48                supports_wallet: true,
49            },
50        ]
51    }
52
53    /// Get variant by protocol version
54    pub fn for_version(version: ProtocolVersion) -> Option<Self> {
55        Self::all_variants()
56            .into_iter()
57            .find(|v| v.version == version)
58    }
59
60    /// Check if this variant is suitable for production use
61    pub fn is_production_ready(&self) -> bool {
62        self.is_production
63    }
64
65    /// Check if this variant supports mining operations
66    pub fn supports_mining_operations(&self) -> bool {
67        self.supports_mining
68    }
69
70    /// Check if this variant supports wallet operations
71    pub fn supports_wallet_operations(&self) -> bool {
72        self.supports_wallet
73    }
74}
75
76/// Protocol evolution support
77#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
78pub struct ProtocolEvolution {
79    /// Protocol version number
80    pub version: u32,
81    /// Features enabled in this version
82    pub enabled_features: Vec<String>,
83    /// Features deprecated in this version
84    pub deprecated_features: Vec<String>,
85    /// Breaking changes from previous version
86    pub breaking_changes: Vec<String>,
87}
88
89impl ProtocolEvolution {
90    /// Bitcoin V1 (current)
91    pub fn bitcoin_v1() -> Self {
92        Self {
93            version: 1,
94            enabled_features: vec![
95                "basic_transactions".to_string(),
96                "proof_of_work".to_string(),
97                "economic_model".to_string(),
98                "p2p_networking".to_string(),
99            ],
100            deprecated_features: vec![],
101            breaking_changes: vec![],
102        }
103    }
104
105    /// Bitcoin V2 (future hypothetical)
106    pub fn bitcoin_v2() -> Self {
107        Self {
108            version: 2,
109            enabled_features: vec![
110                "basic_transactions".to_string(),
111                "proof_of_work".to_string(),
112                "economic_model".to_string(),
113                "p2p_networking".to_string(),
114                "advanced_scripting".to_string(),
115                "privacy_features".to_string(),
116            ],
117            deprecated_features: vec!["legacy_addresses".to_string()],
118            breaking_changes: vec![
119                "new_address_format".to_string(),
120                "enhanced_script_engine".to_string(),
121            ],
122        }
123    }
124
125    /// Check if a feature is enabled in this protocol version
126    pub fn has_feature(&self, feature: &str) -> bool {
127        self.enabled_features.contains(&feature.to_string())
128    }
129
130    /// Check if a feature is deprecated in this protocol version
131    pub fn is_deprecated(&self, feature: &str) -> bool {
132        self.deprecated_features.contains(&feature.to_string())
133    }
134}
135
136#[cfg(test)]
137mod tests {
138    use super::*;
139
140    #[test]
141    fn test_protocol_variants() {
142        let variants = ProtocolVariant::all_variants();
143        assert_eq!(variants.len(), 3);
144
145        let mainnet = ProtocolVariant::for_version(ProtocolVersion::BitcoinV1).unwrap();
146        assert_eq!(mainnet.name, "Bitcoin Mainnet");
147        assert!(mainnet.is_production_ready());
148        assert!(mainnet.supports_mining_operations());
149
150        let regtest = ProtocolVariant::for_version(ProtocolVersion::Regtest).unwrap();
151        assert_eq!(regtest.name, "Bitcoin Regtest");
152        assert!(!regtest.is_production_ready());
153        assert!(regtest.supports_mining_operations());
154    }
155
156    #[test]
157    fn test_protocol_variants_all_versions() {
158        let variants = ProtocolVariant::all_variants();
159
160        // Test that all expected variants are present
161        let mainnet = variants
162            .iter()
163            .find(|v| v.version == ProtocolVersion::BitcoinV1)
164            .unwrap();
165        let testnet = variants
166            .iter()
167            .find(|v| v.version == ProtocolVersion::Testnet3)
168            .unwrap();
169        let regtest = variants
170            .iter()
171            .find(|v| v.version == ProtocolVersion::Regtest)
172            .unwrap();
173
174        assert_eq!(mainnet.name, "Bitcoin Mainnet");
175        assert_eq!(testnet.name, "Bitcoin Testnet");
176        assert_eq!(regtest.name, "Bitcoin Regtest");
177    }
178
179    #[test]
180    fn test_protocol_variant_lookup() {
181        // Test valid versions
182        let mainnet = ProtocolVariant::for_version(ProtocolVersion::BitcoinV1).unwrap();
183        let testnet = ProtocolVariant::for_version(ProtocolVersion::Testnet3).unwrap();
184        let regtest = ProtocolVariant::for_version(ProtocolVersion::Regtest).unwrap();
185
186        assert_eq!(mainnet.version, ProtocolVersion::BitcoinV1);
187        assert_eq!(testnet.version, ProtocolVersion::Testnet3);
188        assert_eq!(regtest.version, ProtocolVersion::Regtest);
189    }
190
191    #[test]
192    fn test_protocol_variant_production_readiness() {
193        let mainnet = ProtocolVariant::for_version(ProtocolVersion::BitcoinV1).unwrap();
194        let testnet = ProtocolVariant::for_version(ProtocolVersion::Testnet3).unwrap();
195        let regtest = ProtocolVariant::for_version(ProtocolVersion::Regtest).unwrap();
196
197        assert!(mainnet.is_production_ready());
198        assert!(!testnet.is_production_ready());
199        assert!(!regtest.is_production_ready());
200    }
201
202    #[test]
203    fn test_protocol_variant_mining_support() {
204        let mainnet = ProtocolVariant::for_version(ProtocolVersion::BitcoinV1).unwrap();
205        let testnet = ProtocolVariant::for_version(ProtocolVersion::Testnet3).unwrap();
206        let regtest = ProtocolVariant::for_version(ProtocolVersion::Regtest).unwrap();
207
208        assert!(mainnet.supports_mining_operations());
209        assert!(testnet.supports_mining_operations());
210        assert!(regtest.supports_mining_operations());
211    }
212
213    #[test]
214    fn test_protocol_variant_wallet_support() {
215        let mainnet = ProtocolVariant::for_version(ProtocolVersion::BitcoinV1).unwrap();
216        let testnet = ProtocolVariant::for_version(ProtocolVersion::Testnet3).unwrap();
217        let regtest = ProtocolVariant::for_version(ProtocolVersion::Regtest).unwrap();
218
219        assert!(mainnet.supports_wallet_operations());
220        assert!(testnet.supports_wallet_operations());
221        assert!(regtest.supports_wallet_operations());
222    }
223
224    #[test]
225    fn test_protocol_variant_descriptions() {
226        let mainnet = ProtocolVariant::for_version(ProtocolVersion::BitcoinV1).unwrap();
227        let testnet = ProtocolVariant::for_version(ProtocolVersion::Testnet3).unwrap();
228        let regtest = ProtocolVariant::for_version(ProtocolVersion::Regtest).unwrap();
229
230        assert!(mainnet.description.contains("Production"));
231        assert!(testnet.description.contains("test"));
232        assert!(regtest.description.contains("testing"));
233    }
234
235    #[test]
236    fn test_protocol_variant_serialization() {
237        let mainnet = ProtocolVariant::for_version(ProtocolVersion::BitcoinV1).unwrap();
238        let json = serde_json::to_string(&mainnet).unwrap();
239        let deserialized: ProtocolVariant = serde_json::from_str(&json).unwrap();
240
241        assert_eq!(mainnet.version, deserialized.version);
242        assert_eq!(mainnet.name, deserialized.name);
243        assert_eq!(mainnet.description, deserialized.description);
244        assert_eq!(mainnet.is_production, deserialized.is_production);
245        assert_eq!(mainnet.supports_mining, deserialized.supports_mining);
246        assert_eq!(mainnet.supports_wallet, deserialized.supports_wallet);
247    }
248
249    #[test]
250    fn test_protocol_variant_equality() {
251        let mainnet1 = ProtocolVariant::for_version(ProtocolVersion::BitcoinV1).unwrap();
252        let mainnet2 = ProtocolVariant::for_version(ProtocolVersion::BitcoinV1).unwrap();
253        let testnet = ProtocolVariant::for_version(ProtocolVersion::Testnet3).unwrap();
254
255        assert_eq!(mainnet1, mainnet2);
256        assert_ne!(mainnet1, testnet);
257    }
258
259    #[test]
260    fn test_protocol_evolution() {
261        let v1 = ProtocolEvolution::bitcoin_v1();
262        assert_eq!(v1.version, 1);
263        assert!(v1.has_feature("basic_transactions"));
264        assert!(!v1.is_deprecated("basic_transactions"));
265
266        let v2 = ProtocolEvolution::bitcoin_v2();
267        assert_eq!(v2.version, 2);
268        assert!(v2.has_feature("privacy_features"));
269        assert!(v2.is_deprecated("legacy_addresses"));
270    }
271
272    #[test]
273    fn test_protocol_evolution_v1_features() {
274        let v1 = ProtocolEvolution::bitcoin_v1();
275
276        // Test all V1 features
277        assert!(v1.has_feature("basic_transactions"));
278        assert!(v1.has_feature("proof_of_work"));
279        assert!(v1.has_feature("economic_model"));
280        assert!(v1.has_feature("p2p_networking"));
281
282        // Test that V1 doesn't have V2 features
283        assert!(!v1.has_feature("advanced_scripting"));
284        assert!(!v1.has_feature("privacy_features"));
285
286        // Test that V1 has no deprecated features
287        assert!(!v1.is_deprecated("basic_transactions"));
288        assert!(!v1.is_deprecated("proof_of_work"));
289    }
290
291    #[test]
292    fn test_protocol_evolution_v2_features() {
293        let v2 = ProtocolEvolution::bitcoin_v2();
294
295        // Test V2 has all V1 features
296        assert!(v2.has_feature("basic_transactions"));
297        assert!(v2.has_feature("proof_of_work"));
298        assert!(v2.has_feature("economic_model"));
299        assert!(v2.has_feature("p2p_networking"));
300
301        // Test V2 has new features
302        assert!(v2.has_feature("advanced_scripting"));
303        assert!(v2.has_feature("privacy_features"));
304
305        // Test V2 has deprecated features
306        assert!(v2.is_deprecated("legacy_addresses"));
307
308        // Test V2 has breaking changes
309        assert!(v2
310            .breaking_changes
311            .contains(&"new_address_format".to_string()));
312        assert!(v2
313            .breaking_changes
314            .contains(&"enhanced_script_engine".to_string()));
315    }
316
317    #[test]
318    fn test_protocol_evolution_feature_queries() {
319        let v1 = ProtocolEvolution::bitcoin_v1();
320        let v2 = ProtocolEvolution::bitcoin_v2();
321
322        // Test feature existence
323        assert!(v1.has_feature("basic_transactions"));
324        assert!(!v1.has_feature("nonexistent"));
325        assert!(!v1.has_feature(""));
326
327        // Test deprecation queries
328        assert!(!v1.is_deprecated("basic_transactions"));
329        assert!(v2.is_deprecated("legacy_addresses"));
330        assert!(!v2.is_deprecated("basic_transactions"));
331    }
332
333    #[test]
334    fn test_protocol_evolution_serialization() {
335        let v1 = ProtocolEvolution::bitcoin_v1();
336        let json = serde_json::to_string(&v1).unwrap();
337        let deserialized: ProtocolEvolution = serde_json::from_str(&json).unwrap();
338
339        assert_eq!(v1.version, deserialized.version);
340        assert_eq!(v1.enabled_features, deserialized.enabled_features);
341        assert_eq!(v1.deprecated_features, deserialized.deprecated_features);
342        assert_eq!(v1.breaking_changes, deserialized.breaking_changes);
343    }
344
345    #[test]
346    fn test_protocol_evolution_equality() {
347        let v1_1 = ProtocolEvolution::bitcoin_v1();
348        let v1_2 = ProtocolEvolution::bitcoin_v1();
349        let v2 = ProtocolEvolution::bitcoin_v2();
350
351        assert_eq!(v1_1, v1_2);
352        assert_ne!(v1_1, v2);
353    }
354
355    #[test]
356    fn test_protocol_evolution_version_comparison() {
357        let v1 = ProtocolEvolution::bitcoin_v1();
358        let v2 = ProtocolEvolution::bitcoin_v2();
359
360        assert!(v2.version > v1.version);
361        assert_eq!(v1.version, 1);
362        assert_eq!(v2.version, 2);
363    }
364
365    #[test]
366    fn test_protocol_evolution_feature_sets() {
367        let v1 = ProtocolEvolution::bitcoin_v1();
368        let v2 = ProtocolEvolution::bitcoin_v2();
369
370        // V2 should have all V1 features plus new ones
371        for feature in &v1.enabled_features {
372            assert!(v2.has_feature(feature));
373        }
374
375        // V2 should have additional features
376        assert!(v2.enabled_features.len() > v1.enabled_features.len());
377
378        // V1 should have no deprecated features
379        assert!(v1.deprecated_features.is_empty());
380
381        // V2 should have deprecated features
382        assert!(!v2.deprecated_features.is_empty());
383    }
384}