blockchain_runtime/
config.rs

1//! Configuration types for blockchain runtime
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6use crate::constants::*;
7use crate::security::SecurityConfig;
8use crate::types::NetworkMode;
9
10/// Runtime configuration with security features
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct RuntimeConfig {
13    pub timeout_seconds: u64,
14    pub memory_limit_mb: u64,
15    pub network_mode: NetworkMode,
16    pub enable_monitoring: bool,
17    pub blockchain_config: HashMap<String, serde_json::Value>,
18    /// Security configuration
19    pub security_config: SecurityConfig,
20}
21
22impl Default for RuntimeConfig {
23    fn default() -> Self {
24        Self {
25            timeout_seconds: DEFAULT_TIMEOUT_SECONDS,
26            memory_limit_mb: DEFAULT_MEMORY_LIMIT_MB,
27            network_mode: NetworkMode::Local,
28            enable_monitoring: true,
29            blockchain_config: HashMap::new(),
30            security_config: SecurityConfig::default(),
31        }
32    }
33}
34
35impl RuntimeConfig {
36    /// Create a new runtime configuration
37    pub fn new(
38        timeout_seconds: u64,
39        memory_limit_mb: u64,
40        network_mode: NetworkMode,
41    ) -> Self {
42        Self {
43            timeout_seconds,
44            memory_limit_mb,
45            network_mode,
46            enable_monitoring: true,
47            blockchain_config: HashMap::new(),
48            security_config: SecurityConfig::default(),
49        }
50    }
51
52    /// Create a configuration for local development
53    pub fn local_development() -> Self {
54        Self {
55            timeout_seconds: DEFAULT_TIMEOUT_SECONDS,
56            memory_limit_mb: DEFAULT_MEMORY_LIMIT_MB,
57            network_mode: NetworkMode::Local,
58            enable_monitoring: true,
59            blockchain_config: HashMap::new(),
60            security_config: SecurityConfig::permissive(),
61        }
62    }
63
64    /// Create a configuration for production
65    pub fn production() -> Self {
66        Self {
67            timeout_seconds: DEFAULT_TIMEOUT_SECONDS,
68            memory_limit_mb: DEFAULT_MEMORY_LIMIT_MB,
69            network_mode: NetworkMode::MainnetFork,
70            enable_monitoring: true,
71            blockchain_config: HashMap::new(),
72            security_config: SecurityConfig::strict(),
73        }
74    }
75
76    /// Create a configuration for testing
77    pub fn testing() -> Self {
78        Self {
79            timeout_seconds: 60, // Shorter timeout for tests
80            memory_limit_mb: 256, // Lower memory limit for tests
81            network_mode: NetworkMode::Local,
82            enable_monitoring: false,
83            blockchain_config: HashMap::new(),
84            security_config: SecurityConfig::permissive(),
85        }
86    }
87
88    /// Set security configuration
89    pub fn with_security_config(mut self, security_config: SecurityConfig) -> Self {
90        self.security_config = security_config;
91        self
92    }
93
94    /// Set blockchain-specific configuration
95    pub fn with_blockchain_config(mut self, key: String, value: serde_json::Value) -> Self {
96        self.blockchain_config.insert(key, value);
97        self
98    }
99
100    /// Enable or disable monitoring
101    pub fn with_monitoring(mut self, enabled: bool) -> Self {
102        self.enable_monitoring = enabled;
103        self
104    }
105
106    /// Validate the configuration
107    pub fn validate(&self) -> Result<(), String> {
108        if self.timeout_seconds == 0 {
109            return Err("Timeout cannot be zero".to_string());
110        }
111
112        if self.memory_limit_mb == 0 {
113            return Err("Memory limit cannot be zero".to_string());
114        }
115
116        // Validate security configuration
117        if self.security_config.max_call_depth == 0 {
118            return Err("Maximum call depth cannot be zero".to_string());
119        }
120
121        if self.security_config.max_external_calls == 0 {
122            return Err("Maximum external calls cannot be zero".to_string());
123        }
124
125        if self.security_config.max_gas_limit == 0 {
126            return Err("Maximum gas limit cannot be zero".to_string());
127        }
128
129        if self.security_config.max_memory_bytes == 0 {
130            return Err("Maximum memory bytes cannot be zero".to_string());
131        }
132
133        Ok(())
134    }
135
136    /// Get a human-readable description of the configuration
137    pub fn describe(&self) -> String {
138        format!(
139            "RuntimeConfig: timeout={}s, memory={}MB, network={:?}, monitoring={}, security={}",
140            self.timeout_seconds,
141            self.memory_limit_mb,
142            self.network_mode,
143            self.enable_monitoring,
144            if self.security_config.sandbox_enabled { "strict" } else { "permissive" }
145        )
146    }
147
148    /// Check if this is a development configuration
149    pub fn is_development(&self) -> bool {
150        matches!(self.network_mode, NetworkMode::Local) && 
151        !self.security_config.sandbox_enabled
152    }
153
154    /// Check if this is a production configuration
155    pub fn is_production(&self) -> bool {
156        matches!(self.network_mode, NetworkMode::MainnetFork) && 
157        self.security_config.sandbox_enabled
158    }
159
160    /// Check if this is a test configuration
161    pub fn is_test(&self) -> bool {
162        self.timeout_seconds <= 60 && 
163        self.memory_limit_mb <= 256 && 
164        !self.enable_monitoring
165    }
166}
167
168/// Builder pattern for runtime configuration
169pub struct RuntimeConfigBuilder {
170    config: RuntimeConfig,
171}
172
173impl RuntimeConfigBuilder {
174    /// Create a new builder with default values
175    pub fn new() -> Self {
176        Self {
177            config: RuntimeConfig::default(),
178        }
179    }
180
181    /// Set timeout in seconds
182    pub fn timeout_seconds(mut self, seconds: u64) -> Self {
183        self.config.timeout_seconds = seconds;
184        self
185    }
186
187    /// Set memory limit in MB
188    pub fn memory_limit_mb(mut self, mb: u64) -> Self {
189        self.config.memory_limit_mb = mb;
190        self
191    }
192
193    /// Set network mode
194    pub fn network_mode(mut self, mode: NetworkMode) -> Self {
195        self.config.network_mode = mode;
196        self
197    }
198
199    /// Enable or disable monitoring
200    pub fn monitoring(mut self, enabled: bool) -> Self {
201        self.config.enable_monitoring = enabled;
202        self
203    }
204
205    /// Set security configuration
206    pub fn security_config(mut self, config: SecurityConfig) -> Self {
207        self.config.security_config = config;
208        self
209    }
210
211    /// Add blockchain configuration
212    pub fn blockchain_config(mut self, key: String, value: serde_json::Value) -> Self {
213        self.config.blockchain_config.insert(key, value);
214        self
215    }
216
217    /// Build the final configuration
218    pub fn build(self) -> Result<RuntimeConfig, String> {
219        self.config.validate()?;
220        Ok(self.config)
221    }
222}
223
224impl Default for RuntimeConfigBuilder {
225    fn default() -> Self {
226        Self::new()
227    }
228}