blockchain_runtime/
lib.rs

1//! # Blockchain Runtime
2//!
3//! Blockchain-agnostic runtime abstraction for dynamic analysis, testing, and simulation.
4//!
5//! ## Features
6//!
7//! - **Blockchain-Agnostic**: Works with any blockchain (Ethereum, Solana, etc.)
8//! - **Dynamic Analysis**: Execute code in runtime environments
9//! - **Testing**: Spin up test networks for contract testing
10//! - **Simulation**: Simulate transactions and monitor state changes
11//! - **Metrics Collection**: Track gas, compute units, state changes
12//! - **Event Monitoring**: Capture events and logs
13//! - **Async-First**: Non-blocking runtime operations
14//! - **Security**: Built-in security validation and monitoring
15//!
16//! ## Quick Start
17//!
18//! ```rust,no_run
19//! use blockchain_runtime::{BlockchainRuntime, RuntimeConfig, NetworkMode, DefaultBlockchainRuntime};
20//!
21//! # async fn example() -> anyhow::Result<()> {
22//! // Configure runtime
23//! let config = RuntimeConfig::default();
24//!
25//! // Create runtime
26//! let runtime = DefaultBlockchainRuntime::new("ethereum".to_string());
27//! let env = runtime.create_environment(config).await?;
28//!
29//! // Execute code
30//! // let result = runtime.execute(&env, code_path, inputs).await?;
31//! // println!("Execution result: {:?}", result.success);
32//! # Ok(())
33//! # }
34//! ```
35
36// Re-export main types and traits
37pub use config::*;
38pub use runtime::*;
39pub use security::*;
40pub use types::*;
41
42// Module declarations
43mod config;
44mod constants;
45mod runtime;
46mod security;
47mod types;
48
49// Optional tracing
50#[cfg(feature = "tracing")]
51use tracing::info;
52
53#[cfg(not(feature = "tracing"))]
54macro_rules! info {
55    ($($arg:tt)*) => {};
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn test_runtime_config_default() {
64        let config = RuntimeConfig::default();
65        assert_eq!(config.timeout_seconds, 300);
66        assert_eq!(config.memory_limit_mb, 1024);
67        assert_eq!(config.network_mode, NetworkMode::Local);
68        assert!(config.enable_monitoring);
69    }
70
71    #[test]
72    fn test_runtime_environment_creation() {
73        let env = RuntimeEnvironment {
74            environment_id: "test-env".to_string(),
75            blockchain_id: "ethereum".to_string(),
76            runtime_type: RuntimeType::Docker,
77            endpoint_url: "http://localhost:8545".to_string(),
78            state: EnvironmentState::Ready,
79            metadata: HashMap::new(),
80        };
81
82        assert_eq!(env.environment_id, "test-env");
83        assert_eq!(env.state, EnvironmentState::Ready);
84    }
85
86    #[test]
87    fn test_execution_result() {
88        let result = ExecutionResult {
89            execution_id: "exec-1".to_string(),
90            success: true,
91            return_value: Some(serde_json::json!({"value": 42})),
92            error: None,
93            metrics: HashMap::new(),
94            state_changes: vec![],
95            events: vec![],
96            execution_time_ms: 150,
97        };
98
99        assert!(result.success);
100        assert!(result.error.is_none());
101        assert_eq!(result.execution_time_ms, 150);
102    }
103
104    #[test]
105    fn test_state_change() {
106        let change = StateChange {
107            key: "balance".to_string(),
108            old_value: Some(serde_json::json!(100)),
109            new_value: serde_json::json!(200),
110            change_type: StateChangeType::Updated,
111        };
112
113        assert_eq!(change.change_type, StateChangeType::Updated);
114    }
115
116    #[test]
117    fn test_runtime_capabilities() {
118        let caps = RuntimeCapabilities::default();
119        assert!(caps.supports_contract_deployment);
120        assert!(caps.supports_function_calls);
121        assert_eq!(caps.max_execution_time_seconds, 300);
122    }
123
124    #[test]
125    fn test_network_modes() {
126        assert_ne!(NetworkMode::Local, NetworkMode::Testnet);
127        assert_ne!(NetworkMode::Testnet, NetworkMode::MainnetFork);
128    }
129
130    #[test]
131    fn test_runtime_types() {
132        assert_ne!(RuntimeType::Docker, RuntimeType::LocalProcess);
133        assert_ne!(RuntimeType::LocalProcess, RuntimeType::InMemory);
134    }
135
136    #[test]
137    fn test_environment_states() {
138        assert_ne!(EnvironmentState::Creating, EnvironmentState::Ready);
139        assert_ne!(EnvironmentState::Ready, EnvironmentState::Running);
140    }
141
142    #[test]
143    fn test_metric_types() {
144        assert_eq!(MetricType::Gas, MetricType::Gas);
145        assert_ne!(MetricType::Gas, MetricType::ComputeUnits);
146    }
147
148    #[test]
149    fn test_serialization() {
150        let config = RuntimeConfig::default();
151        let json = serde_json::to_string(&config).unwrap();
152        let deserialized: RuntimeConfig = serde_json::from_str(&json).unwrap();
153
154        assert_eq!(deserialized.timeout_seconds, config.timeout_seconds);
155        assert_eq!(deserialized.network_mode, config.network_mode);
156    }
157
158    #[test]
159    fn test_security_config_default() {
160        let security_config = SecurityConfig::default();
161        assert!(security_config.sandbox_enabled);
162        assert!(security_config.reentrancy_protection);
163        assert!(security_config.overflow_detection);
164        assert!(security_config.access_control_verification);
165        assert_eq!(security_config.max_call_depth, 1024);
166        assert_eq!(security_config.max_external_calls, 100);
167        assert!(security_config.gas_limit_enforcement);
168        assert_eq!(security_config.max_gas_limit, 10_000_000);
169        assert!(security_config.memory_limit_enforcement);
170        assert_eq!(security_config.max_memory_bytes, 100 * 1024 * 1024);
171    }
172
173    #[test]
174    fn test_security_violation_creation() {
175        let violation = SecurityViolation {
176            violation_type: SecurityViolationType::ReentrancyAttack,
177            description: "Reentrancy attack detected".to_string(),
178            severity: SecuritySeverity::Critical,
179            timestamp: SystemTime::now()
180                .duration_since(UNIX_EPOCH)
181                .unwrap()
182                .as_secs(),
183            context: HashMap::new(),
184        };
185
186        assert_eq!(violation.violation_type, SecurityViolationType::ReentrancyAttack);
187        assert_eq!(violation.severity, SecuritySeverity::Critical);
188    }
189
190    #[test]
191    fn test_secure_execution_context() {
192        let mut context = SecureExecutionContext::default();
193        context.call_depth = 5;
194        context.external_call_count = 10;
195        context.gas_used = 1000;
196        context.memory_used = 1024;
197        context.call_stack.push("function1".to_string());
198        context.call_stack.push("function2".to_string());
199
200        assert_eq!(context.call_depth, 5);
201        assert_eq!(context.external_call_count, 10);
202        assert_eq!(context.gas_used, 1000);
203        assert_eq!(context.memory_used, 1024);
204        assert_eq!(context.call_stack.len(), 2);
205    }
206
207    #[test]
208    fn test_access_control_check() {
209        let check = AccessControlCheck {
210            function_name: "withdraw".to_string(),
211            caller: "0x123".to_string(),
212            required_role: Some("owner".to_string()),
213            has_permission: true,
214            check_timestamp: SystemTime::now()
215                .duration_since(UNIX_EPOCH)
216                .unwrap()
217                .as_secs(),
218        };
219
220        assert_eq!(check.function_name, "withdraw");
221        assert_eq!(check.caller, "0x123");
222        assert_eq!(check.required_role, Some("owner".to_string()));
223        assert!(check.has_permission);
224    }
225
226    #[test]
227    fn test_execution_result_with_security() {
228        let security_context = SecureExecutionContext::default();
229        let security_violations = vec![SecurityViolation {
230            violation_type: SecurityViolationType::IntegerOverflow,
231            description: "Integer overflow detected".to_string(),
232            severity: SecuritySeverity::High,
233            timestamp: SystemTime::now()
234                .duration_since(UNIX_EPOCH)
235                .unwrap()
236                .as_secs(),
237            context: HashMap::new(),
238        }];
239
240        let result = ExecutionResult {
241            execution_id: "exec-1".to_string(),
242            success: false,
243            return_value: None,
244            error: Some("Security violation detected".to_string()),
245            metrics: HashMap::new(),
246            state_changes: vec![],
247            events: vec![],
248            execution_time_ms: 150,
249            security_context,
250            security_violations,
251        };
252
253        assert!(!result.success);
254        assert!(result.error.is_some());
255        assert_eq!(result.security_violations.len(), 1);
256        assert_eq!(result.security_violations[0].violation_type, SecurityViolationType::IntegerOverflow);
257    }
258
259    #[test]
260    fn test_runtime_config_with_security() {
261        let config = RuntimeConfig::default();
262        assert!(config.security_config.sandbox_enabled);
263        assert!(config.security_config.reentrancy_protection);
264        assert!(config.security_config.overflow_detection);
265        assert!(config.security_config.access_control_verification);
266    }
267
268    #[test]
269    fn test_security_violation_types() {
270        assert_ne!(SecurityViolationType::ReentrancyAttack, SecurityViolationType::IntegerOverflow);
271        assert_ne!(SecurityViolationType::AccessControlViolation, SecurityViolationType::ResourceLimitExceeded);
272        assert_eq!(SecurityViolationType::GasLimitExceeded, SecurityViolationType::GasLimitExceeded);
273    }
274
275    #[test]
276    fn test_security_severity_levels() {
277        assert_ne!(SecuritySeverity::Low, SecuritySeverity::Medium);
278        assert_ne!(SecuritySeverity::Medium, SecuritySeverity::High);
279        assert_ne!(SecuritySeverity::High, SecuritySeverity::Critical);
280        assert_eq!(SecuritySeverity::Critical, SecuritySeverity::Critical);
281    }
282
283    #[test]
284    fn test_security_serialization() {
285        let security_config = SecurityConfig::default();
286        let json = serde_json::to_string(&security_config).unwrap();
287        let deserialized: SecurityConfig = serde_json::from_str(&json).unwrap();
288
289        assert_eq!(deserialized.sandbox_enabled, security_config.sandbox_enabled);
290        assert_eq!(deserialized.reentrancy_protection, security_config.reentrancy_protection);
291        assert_eq!(deserialized.overflow_detection, security_config.overflow_detection);
292    }
293}
294