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