use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::constants::*;
use crate::security::SecurityConfig;
use crate::types::NetworkMode;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RuntimeConfig {
pub timeout_seconds: u64,
pub memory_limit_mb: u64,
pub network_mode: NetworkMode,
pub enable_monitoring: bool,
pub blockchain_config: HashMap<String, serde_json::Value>,
pub security_config: SecurityConfig,
}
impl Default for RuntimeConfig {
fn default() -> Self {
Self {
timeout_seconds: DEFAULT_TIMEOUT_SECONDS,
memory_limit_mb: DEFAULT_MEMORY_LIMIT_MB,
network_mode: NetworkMode::Local,
enable_monitoring: true,
blockchain_config: HashMap::new(),
security_config: SecurityConfig::default(),
}
}
}
impl RuntimeConfig {
pub fn new(
timeout_seconds: u64,
memory_limit_mb: u64,
network_mode: NetworkMode,
) -> Self {
Self {
timeout_seconds,
memory_limit_mb,
network_mode,
enable_monitoring: true,
blockchain_config: HashMap::new(),
security_config: SecurityConfig::default(),
}
}
pub fn local_development() -> Self {
Self {
timeout_seconds: DEFAULT_TIMEOUT_SECONDS,
memory_limit_mb: DEFAULT_MEMORY_LIMIT_MB,
network_mode: NetworkMode::Local,
enable_monitoring: true,
blockchain_config: HashMap::new(),
security_config: SecurityConfig::permissive(),
}
}
pub fn production() -> Self {
Self {
timeout_seconds: DEFAULT_TIMEOUT_SECONDS,
memory_limit_mb: DEFAULT_MEMORY_LIMIT_MB,
network_mode: NetworkMode::MainnetFork,
enable_monitoring: true,
blockchain_config: HashMap::new(),
security_config: SecurityConfig::strict(),
}
}
pub fn testing() -> Self {
Self {
timeout_seconds: 60, memory_limit_mb: 256, network_mode: NetworkMode::Local,
enable_monitoring: false,
blockchain_config: HashMap::new(),
security_config: SecurityConfig::permissive(),
}
}
pub fn with_security_config(mut self, security_config: SecurityConfig) -> Self {
self.security_config = security_config;
self
}
pub fn with_blockchain_config(mut self, key: String, value: serde_json::Value) -> Self {
self.blockchain_config.insert(key, value);
self
}
pub fn with_monitoring(mut self, enabled: bool) -> Self {
self.enable_monitoring = enabled;
self
}
pub fn validate(&self) -> Result<(), String> {
if self.timeout_seconds == 0 {
return Err("Timeout cannot be zero".to_string());
}
if self.memory_limit_mb == 0 {
return Err("Memory limit cannot be zero".to_string());
}
if self.security_config.max_call_depth == 0 {
return Err("Maximum call depth cannot be zero".to_string());
}
if self.security_config.max_external_calls == 0 {
return Err("Maximum external calls cannot be zero".to_string());
}
if self.security_config.max_gas_limit == 0 {
return Err("Maximum gas limit cannot be zero".to_string());
}
if self.security_config.max_memory_bytes == 0 {
return Err("Maximum memory bytes cannot be zero".to_string());
}
Ok(())
}
pub fn describe(&self) -> String {
format!(
"RuntimeConfig: timeout={}s, memory={}MB, network={:?}, monitoring={}, security={}",
self.timeout_seconds,
self.memory_limit_mb,
self.network_mode,
self.enable_monitoring,
if self.security_config.sandbox_enabled { "strict" } else { "permissive" }
)
}
pub fn is_development(&self) -> bool {
matches!(self.network_mode, NetworkMode::Local) &&
!self.security_config.sandbox_enabled
}
pub fn is_production(&self) -> bool {
matches!(self.network_mode, NetworkMode::MainnetFork) &&
self.security_config.sandbox_enabled
}
pub fn is_test(&self) -> bool {
self.timeout_seconds <= 60 &&
self.memory_limit_mb <= 256 &&
!self.enable_monitoring
}
}
pub struct RuntimeConfigBuilder {
config: RuntimeConfig,
}
impl RuntimeConfigBuilder {
pub fn new() -> Self {
Self {
config: RuntimeConfig::default(),
}
}
pub fn timeout_seconds(mut self, seconds: u64) -> Self {
self.config.timeout_seconds = seconds;
self
}
pub fn memory_limit_mb(mut self, mb: u64) -> Self {
self.config.memory_limit_mb = mb;
self
}
pub fn network_mode(mut self, mode: NetworkMode) -> Self {
self.config.network_mode = mode;
self
}
pub fn monitoring(mut self, enabled: bool) -> Self {
self.config.enable_monitoring = enabled;
self
}
pub fn security_config(mut self, config: SecurityConfig) -> Self {
self.config.security_config = config;
self
}
pub fn blockchain_config(mut self, key: String, value: serde_json::Value) -> Self {
self.config.blockchain_config.insert(key, value);
self
}
pub fn build(self) -> Result<RuntimeConfig, String> {
self.config.validate()?;
Ok(self.config)
}
}
impl Default for RuntimeConfigBuilder {
fn default() -> Self {
Self::new()
}
}