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