diff --git a/executor/src/config.rs b/executor/src/config.rs index 55c2e552..56e843b9 100644 --- a/executor/src/config.rs +++ b/executor/src/config.rs @@ -1,17 +1,18 @@ -use serde_derive::Deserialize; +use serde_derive::{Deserialize, Serialize}; +use anyhow::{Result, bail}; -#[derive(Deserialize)] +#[derive(Deserialize, Serialize, Debug, Clone)] pub struct Module { pub address: String, } -#[derive(Deserialize)] +#[derive(Deserialize, Serialize, Debug, Clone)] pub struct Modules { pub llm: Module, pub web: Module, } -#[derive(Deserialize)] +#[derive(Deserialize, Serialize, Debug, Clone)] pub struct Config { pub modules: Modules, pub cache_dir: String, @@ -21,3 +22,24 @@ pub struct Config { #[serde(flatten)] pub base: genvm_common::BaseConfig, } + +impl Config { + /// Validates the configuration to ensure all paths and module addresses are present. + pub fn validate(&self) -> Result<()> { + // Ensure module addresses are not empty + if self.modules.llm.address.is_empty() { + bail!("Config Error: LLM module address cannot be empty"); + } + if self.modules.web.address.is_empty() { + bail!("Config Error: Web module address cannot be empty"); + } + + // Ensure critical directories are specified + if self.cache_dir.is_empty() || self.runners_dir.is_empty() { + bail!("Config Error: Critical directory paths (cache/runners) cannot be empty"); + } + + log_info!("Configuration validated successfully"); + Ok(()) + } +} diff --git a/executor/src/lib.rs b/executor/src/lib.rs index a63da529..ed832efa 100644 --- a/executor/src/lib.rs +++ b/executor/src/lib.rs @@ -16,6 +16,10 @@ pub use host::{Host, SlotID}; use anyhow::Result; use wasi::genlayer_sdk::ExtendedMessage; +// --- ADDED THIS FOR PERFORMANCE TRACING --- +use std::time::Instant; +// ------------------------------------------ + use std::{str::FromStr, sync::Arc}; #[derive(Default, Debug, serde::Serialize)] @@ -24,6 +28,9 @@ pub struct Metrics { pub host: host::Metrics, pub web_module: modules::Metrics, pub llm_module: modules::Metrics, + // --- ADDED FIELD FOR EXECUTION TIME --- + pub execution_time_us: u128, + // -------------------------------------- } pub fn create_supervisor( @@ -33,6 +40,10 @@ pub fn create_supervisor( shared_data: sync::DArc, message: &domain::MessageData, ) -> Result> { + // --- ADDED CONFIG VALIDATION --- + config.validate()?; + // ------------------------------- + let metrics = shared_data.gep(|x| &x.metrics); let modules = modules::All { @@ -88,6 +99,10 @@ pub async fn run_with_impl( supervisor: Arc, permissions: &str, ) -> anyhow::Result { + // --- START EXECUTION TIMER --- + let start_instant = Instant::now(); + // ----------------------------- + let storage_pages_limit = supervisor.get_storage_limiter(); let mut topmost_storage = rt::vm::storage::Storage::new( @@ -181,6 +196,19 @@ pub async fn run_with_impl( let run_result = vm.run().await?; + // --- LOG PERFORMANCE METRICS AND POPULATE SHARED DATA --- + let exec_duration = start_instant.elapsed().as_micros(); + + // This fixes the issue where the field was never populated + supervisor.shared_data.metrics.gep_mut(|m| m.execution_time_us = exec_duration); + + log_info!( + contract = %entry_data.message.contract_address, + duration_us = %exec_duration; + "Intelligent Contract execution performance trace" + ); + // ------------------------------------------------------- + Ok(rt::vm::FullResult { fingerprint: run_result.fingerprint, kind: match &run_result.run_ok {