diff --git a/tee-worker/Cargo.lock b/tee-worker/Cargo.lock index edf030e078..0a9fd4f4ea 100644 --- a/tee-worker/Cargo.lock +++ b/tee-worker/Cargo.lock @@ -2949,7 +2949,9 @@ dependencies = [ "itc-parentchain-indirect-calls-executor", "itc-parentchain-test", "itp-api-client-types", + "itp-enclave-metrics", "itp-node-api", + "itp-ocall-api", "itp-sgx-crypto", "itp-stf-executor", "itp-stf-primitives", @@ -4436,6 +4438,7 @@ dependencies = [ "itc-rest-client", "itp-ocall-api", "itp-stf-primitives", + "itp-test", "itp-types", "itp-utils", "lc-common", @@ -4584,6 +4587,8 @@ dependencies = [ "http 0.2.9", "http_req 0.8.1 (git+https://github.com/integritee-network/http_req?branch=master)", "itc-rest-client", + "itp-enclave-metrics", + "itp-ocall-api", "itp-settings", "itp-sgx-io", "itp-sgx-temp-dir", diff --git a/tee-worker/app-libs/parentchain-interface/Cargo.toml b/tee-worker/app-libs/parentchain-interface/Cargo.toml index 0faa9d76da..46cd6d9f6d 100644 --- a/tee-worker/app-libs/parentchain-interface/Cargo.toml +++ b/tee-worker/app-libs/parentchain-interface/Cargo.toml @@ -13,7 +13,9 @@ ita-sgx-runtime = { path = "../sgx-runtime", default-features = false } ita-stf = { path = "../stf", default-features = false } itc-parentchain-indirect-calls-executor = { path = "../../core/parentchain/indirect-calls-executor", default-features = false } itp-api-client-types = { path = "../../core-primitives/node-api/api-client-types", default-features = false } +itp-enclave-metrics = { path = "../../core-primitives/enclave-metrics", default-features = false } itp-node-api = { path = "../../core-primitives/node-api", default-features = false } +itp-ocall-api = { path = "../../core-primitives/ocall-api", default-features = false } itp-stf-primitives = { path = "../../core-primitives/stf-primitives", default-features = false } itp-types = { path = "../../core-primitives/types", default-features = false } diff --git a/tee-worker/app-libs/parentchain-interface/src/integritee/event_handler.rs b/tee-worker/app-libs/parentchain-interface/src/integritee/event_handler.rs index 5a11d596c5..015cdaee70 100644 --- a/tee-worker/app-libs/parentchain-interface/src/integritee/event_handler.rs +++ b/tee-worker/app-libs/parentchain-interface/src/integritee/event_handler.rs @@ -20,6 +20,8 @@ pub use ita_sgx_runtime::{Balance, Index}; use ita_stf::{Getter, TrustedCall, TrustedCallSigned}; use itc_parentchain_indirect_calls_executor::error::Error; use itp_api_client_types::StaticEvent; +use itp_enclave_metrics::EnclaveMetric; +use itp_ocall_api::EnclaveMetricsOCallApi; use itp_stf_primitives::{traits::IndirectExecutor, types::TrustedOperation}; use itp_types::{ parentchain::{ @@ -34,13 +36,20 @@ use litentry_primitives::{Assertion, Identity, ValidationData, Web3Network}; use log::*; use sp_core::{blake2_256, H160}; use sp_std::vec::Vec; -use std::{format, string::String, sync::Arc}; +use std::{format, string::String, sync::Arc, time::Instant}; -pub struct ParentchainEventHandler { +pub struct ParentchainEventHandler +where + MetricsApi: EnclaveMetricsOCallApi, +{ pub assertion_repository: Arc, + pub metrics_api: Arc, } -impl ParentchainEventHandler { +impl ParentchainEventHandler +where + MetricsApi: EnclaveMetricsOCallApi, +{ fn link_identity>( executor: &Executor, account: &AccountId, @@ -196,17 +205,27 @@ impl ParentchainEventHandler { })?; decrypted_secrets.push(secret); } + let start_time = Instant::now(); self.assertion_repository .save(id, (byte_code, decrypted_secrets)) .map_err(Error::AssertionCreatedHandling)?; + let duration = start_time.elapsed(); + if let Err(e) = self + .metrics_api + .update_metric(EnclaveMetric::DynamicAssertionSaveTime(duration)) + { + warn!("Failed to update DynamicAssertionSaveTime metric with error: {:?}", e); + } + Ok(()) } } -impl HandleParentchainEvents - for ParentchainEventHandler +impl HandleParentchainEvents + for ParentchainEventHandler where Executor: IndirectExecutor, + MetricsApi: EnclaveMetricsOCallApi, { fn handle_events( &self, diff --git a/tee-worker/core-primitives/enclave-metrics/src/lib.rs b/tee-worker/core-primitives/enclave-metrics/src/lib.rs index 0190c32b67..0d311aa2d7 100644 --- a/tee-worker/core-primitives/enclave-metrics/src/lib.rs +++ b/tee-worker/core-primitives/enclave-metrics/src/lib.rs @@ -49,4 +49,6 @@ pub enum EnclaveMetric { SuccessfullVCIssuance, FailedVCIssuance, ParentchainEventProcessed(String), + DynamicAssertionSaveTime(Duration), + DynamicAssertionGetTime(Duration), } diff --git a/tee-worker/enclave-runtime/Cargo.lock b/tee-worker/enclave-runtime/Cargo.lock index 1e4f7522d4..3cb495b83b 100644 --- a/tee-worker/enclave-runtime/Cargo.lock +++ b/tee-worker/enclave-runtime/Cargo.lock @@ -1970,7 +1970,9 @@ dependencies = [ "ita-stf", "itc-parentchain-indirect-calls-executor", "itp-api-client-types", + "itp-enclave-metrics", "itp-node-api", + "itp-ocall-api", "itp-stf-primitives", "itp-types", "lc-dynamic-assertion", @@ -3110,6 +3112,8 @@ dependencies = [ "hex", "http", "itc-rest-client", + "itp-enclave-metrics", + "itp-ocall-api", "itp-settings", "itp-sgx-io", "itp-sgx-temp-dir", diff --git a/tee-worker/enclave-runtime/src/initialization/global_components.rs b/tee-worker/enclave-runtime/src/initialization/global_components.rs index 84c335789d..5255d5303e 100644 --- a/tee-worker/enclave-runtime/src/initialization/global_components.rs +++ b/tee-worker/enclave-runtime/src/initialization/global_components.rs @@ -177,7 +177,7 @@ pub type IntegriteeParentchainIndirectCallsExecutor = IndirectCallsExecutor< EnclaveTopPoolAuthor, EnclaveNodeMetadataRepository, EventCreator, - integritee::ParentchainEventHandler, + integritee::ParentchainEventHandler, EnclaveTrustedCallSigned, EnclaveGetter, >; diff --git a/tee-worker/enclave-runtime/src/initialization/parentchain/common.rs b/tee-worker/enclave-runtime/src/initialization/parentchain/common.rs index 5dabe3e328..52b345d75a 100644 --- a/tee-worker/enclave-runtime/src/initialization/parentchain/common.rs +++ b/tee-worker/enclave-runtime/src/initialization/parentchain/common.rs @@ -70,8 +70,10 @@ pub(crate) fn create_integritee_parentchain_block_importer( let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; let repository = GLOBAL_ASSERTION_REPOSITORY.get()?; - let parentchain_event_handler = - LitentryParentchainEventHandler { assertion_repository: repository }; + let parentchain_event_handler = LitentryParentchainEventHandler { + assertion_repository: repository, + metrics_api: ocall_api.clone(), + }; let stf_enclave_signer = Arc::new(EnclaveStfEnclaveSigner::new( state_observer, diff --git a/tee-worker/litentry/core/assertion-build/Cargo.toml b/tee-worker/litentry/core/assertion-build/Cargo.toml index 8a4d1e0d1b..1e21d217a4 100644 --- a/tee-worker/litentry/core/assertion-build/Cargo.toml +++ b/tee-worker/litentry/core/assertion-build/Cargo.toml @@ -58,6 +58,7 @@ env_logger = "0.10.0" lc-mock-server = { path = "../mock-server" } litentry-hex-utils = { path = "../../../../primitives/hex" } ethabi = { version = "18.0.0", default-features = false } +itp-test = { path = "../../../core-primitives/test", default-features = false } [features] default = ["std"] @@ -97,4 +98,5 @@ std = [ "lc-dynamic-assertion/std", "lc-evm-dynamic-assertions/std", ] +test = ["itp-test/sgx"] development = [] diff --git a/tee-worker/litentry/core/assertion-build/src/dynamic/mod.rs b/tee-worker/litentry/core/assertion-build/src/dynamic/mod.rs index 5cc4c19710..374f810ad0 100644 --- a/tee-worker/litentry/core/assertion-build/src/dynamic/mod.rs +++ b/tee-worker/litentry/core/assertion-build/src/dynamic/mod.rs @@ -15,6 +15,7 @@ // along with Litentry. If not, see . use crate::{dynamic::repository::SmartContractByteCode, *}; +use itp_ocall_api::EnclaveMetricsOCallApi; use itp_types::Assertion; use lc_credentials::{assertion_logic::AssertionLogic, Credential, IssuerRuntimeVersion}; use lc_dynamic_assertion::{AssertionExecutor, AssertionLogicRepository}; @@ -27,12 +28,14 @@ pub mod repository; pub fn build< SC: AssertionLogicRepository)>, + MetricsApi: EnclaveMetricsOCallApi, >( req: &AssertionBuildRequest, params: DynamicParams, repository: Arc, + metrics_api: Arc, ) -> Result<(Credential, Vec)> { - let executor = EvmAssertionExecutor { assertion_repository: repository }; + let executor = EvmAssertionExecutor { assertion_repository: repository, metrics_api }; let execution_params = params.clone(); let result = executor .execute( @@ -85,6 +88,7 @@ pub fn build< #[cfg(test)] pub mod assertion_test { use crate::dynamic::{build, repository::InMemorySmartContractRepo}; + use itp_test::mock::metrics_ocall_mock::MetricsOCallMock; use itp_types::Assertion; use lc_mock_server::run; use lc_stf_task_sender::AssertionBuildRequest; @@ -93,6 +97,7 @@ pub mod assertion_test { DynamicContractParams, DynamicParams, Identity, IdentityString, Web3Network, }; use sp_core::{crypto::AccountId32, H160}; + use std::sync::Arc; #[test] pub fn test_a20_true() { @@ -131,9 +136,11 @@ pub mod assertion_test { }; let repository = InMemorySmartContractRepo::new(); + let metrics_api = Arc::new(MetricsOCallMock::default()); // when - let (credential, vc_logs) = build(&request, dynamic_params, repository.into()).unwrap(); + let (credential, vc_logs) = + build(&request, dynamic_params, repository.into(), metrics_api).unwrap(); for log in &vc_logs { println!("{}", log); @@ -174,9 +181,11 @@ pub mod assertion_test { }; let repository = InMemorySmartContractRepo::new(); + let metrics_api = Arc::new(MetricsOCallMock::default()); // when - let (credential, _) = build(&request, dynamic_params, repository.into()).unwrap(); + let (credential, _) = + build(&request, dynamic_params, repository.into(), metrics_api).unwrap(); println!("Credential is: {:?}", credential); @@ -215,9 +224,11 @@ pub mod assertion_test { }; let repository = InMemorySmartContractRepo::new(); + let metrics_api = Arc::new(MetricsOCallMock::default()); // when - let (credential, _) = build(&request, dynamic_params, repository.into()).unwrap(); + let (credential, _) = + build(&request, dynamic_params, repository.into(), metrics_api).unwrap(); println!("Credential is: {:?}", credential); @@ -253,9 +264,11 @@ pub mod assertion_test { }; let repository = InMemorySmartContractRepo::new(); + let metrics_api = Arc::new(MetricsOCallMock::default()); // when - let (credential, _) = build(&request, dynamic_params, repository.into()).unwrap(); + let (credential, _) = + build(&request, dynamic_params, repository.into(), metrics_api).unwrap(); // then assert!(!credential.credential_subject.values[0]); @@ -304,9 +317,11 @@ pub mod assertion_test { }; let repository = InMemorySmartContractRepo::new(); + let metrics_api = Arc::new(MetricsOCallMock::default()); // when - let (credential, _) = build(&request, dynamic_params, repository.into()).unwrap(); + let (credential, _) = + build(&request, dynamic_params, repository.into(), metrics_api).unwrap(); println!("Credential is: {:?}", credential); diff --git a/tee-worker/litentry/core/evm-dynamic-assertions/Cargo.toml b/tee-worker/litentry/core/evm-dynamic-assertions/Cargo.toml index 87002a3b6b..8bad962754 100644 --- a/tee-worker/litentry/core/evm-dynamic-assertions/Cargo.toml +++ b/tee-worker/litentry/core/evm-dynamic-assertions/Cargo.toml @@ -33,6 +33,8 @@ serde_json = { version = "1.0", default-features = false, features = ["alloc"] } # local itc-rest-client = { path = "../../../core/rest-client", default-features = false } +itp-enclave-metrics = { path = "../../../core-primitives/enclave-metrics", default-features = false } +itp-ocall-api = { path = "../../../core-primitives/ocall-api", default-features = false } itp-settings = { path = "../../../core-primitives/settings" } itp-sgx-io = { path = "../../../core-primitives/sgx/io", default-features = false } lc-dynamic-assertion = { path = "../dynamic-assertion", default-features = false } diff --git a/tee-worker/litentry/core/evm-dynamic-assertions/src/lib.rs b/tee-worker/litentry/core/evm-dynamic-assertions/src/lib.rs index 6d7f9ab506..9a84a4dcec 100644 --- a/tee-worker/litentry/core/evm-dynamic-assertions/src/lib.rs +++ b/tee-worker/litentry/core/evm-dynamic-assertions/src/lib.rs @@ -44,6 +44,8 @@ use evm::{ executor::stack::{MemoryStackState, StackExecutor, StackSubstateMetadata}, Config, ExitReason, }; +use itp_enclave_metrics::EnclaveMetric; +use itp_ocall_api::EnclaveMetricsOCallApi; use lc_dynamic_assertion::{ AssertionExecutor, AssertionLogicRepository, AssertionResult, Identity, IdentityNetworkTuple, Web3Network, @@ -52,6 +54,7 @@ use std::{ collections::BTreeMap, string::{String, ToString}, sync::Arc, + time::Instant, vec, vec::Vec, }; @@ -70,8 +73,9 @@ pub type AssertionParams = Vec; pub type SmartContractByteCode = Vec; pub type AssertionRepositoryItem = (SmartContractByteCode, Vec); -pub struct EvmAssertionExecutor { +pub struct EvmAssertionExecutor { pub assertion_repository: Arc, + pub metrics_api: Arc, } pub fn execute_smart_contract( @@ -103,8 +107,11 @@ pub fn execute_smart_contract( (reason, data, precompiles.contract_logs.take()) } -impl> - AssertionExecutor for EvmAssertionExecutor +impl AssertionExecutor + for EvmAssertionExecutor +where + A: AssertionLogicRepository, + MetricsApi: EnclaveMetricsOCallApi, { fn execute( &self, @@ -112,11 +119,19 @@ impl> assertion_params: AssertionParams, identities: &[IdentityNetworkTuple], ) -> Result { + let start_time = Instant::now(); let (smart_contract_byte_code, secrets) = self .assertion_repository .get(&assertion_id) .map_err(|_| "Could not access assertion repository")? .ok_or("Assertion not found")?; + let duration = start_time.elapsed(); + if let Err(e) = + self.metrics_api.update_metric(EnclaveMetric::DynamicAssertionGetTime(duration)) + { + log::warn!("Failed to update DynamicAssertionGetTime metric with error: {:?}", e); + } + let input = prepare_execute_call_input(identities, secrets, assertion_params) .map_err(|_| "Could not prepare evm execution input")?; diff --git a/tee-worker/litentry/core/stf-task/receiver/src/handler/assertion.rs b/tee-worker/litentry/core/stf-task/receiver/src/handler/assertion.rs index 97e2fc8767..ddd742b395 100644 --- a/tee-worker/litentry/core/stf-task/receiver/src/handler/assertion.rs +++ b/tee-worker/litentry/core/stf-task/receiver/src/handler/assertion.rs @@ -16,7 +16,10 @@ #![allow(clippy::result_large_err)] -use crate::{handler::TaskHandler, EnclaveOnChainOCallApi, StfTaskContext, TrustedCall, H256}; +use crate::{ + handler::TaskHandler, EnclaveMetricsOCallApi, EnclaveOnChainOCallApi, StfTaskContext, + TrustedCall, H256, +}; use ita_sgx_runtime::Hash; use ita_stf::{Getter, TrustedCallSigned}; use itp_sgx_crypto::{key_repository::AccessKey, ShieldingCryptoEncrypt}; @@ -50,7 +53,7 @@ pub(crate) struct AssertionHandler< A: AuthorApi, S: StfEnclaveSigning, H: HandleState, - O: EnclaveOnChainOCallApi, + O: EnclaveOnChainOCallApi + EnclaveMetricsOCallApi, AR: AssertionLogicRepository, > where ShieldingKeyRepository: AccessKey, @@ -69,7 +72,7 @@ where S: StfEnclaveSigning, H: HandleState, H::StateT: SgxExternalitiesTrait, - O: EnclaveOnChainOCallApi, + O: EnclaveOnChainOCallApi + EnclaveMetricsOCallApi, AR: AssertionLogicRepository, { type Error = VCMPError; @@ -144,7 +147,7 @@ pub fn create_credential_str< A: AuthorApi, S: StfEnclaveSigning, H: HandleState, - O: EnclaveOnChainOCallApi, + O: EnclaveOnChainOCallApi + EnclaveMetricsOCallApi, AR: AssertionLogicRepository, >( req: &AssertionBuildRequest, @@ -289,6 +292,7 @@ where req, params, context.assertion_repository.clone(), + context.ocall_api.clone(), )?; vc_logs = Some(result.1); Ok(result.0) diff --git a/tee-worker/litentry/core/stf-task/receiver/src/handler/identity_verification.rs b/tee-worker/litentry/core/stf-task/receiver/src/handler/identity_verification.rs index bf7e0f27e8..d0d47784aa 100644 --- a/tee-worker/litentry/core/stf-task/receiver/src/handler/identity_verification.rs +++ b/tee-worker/litentry/core/stf-task/receiver/src/handler/identity_verification.rs @@ -15,8 +15,8 @@ // along with Litentry. If not, see . use crate::{ - handler::TaskHandler, EnclaveOnChainOCallApi, Getter, StfTaskContext, TrustedCall, - TrustedCallSigned, + handler::TaskHandler, EnclaveMetricsOCallApi, EnclaveOnChainOCallApi, Getter, StfTaskContext, + TrustedCall, TrustedCallSigned, }; use ita_sgx_runtime::Hash; use itp_sgx_crypto::{key_repository::AccessKey, ShieldingCryptoEncrypt}; @@ -37,7 +37,7 @@ pub(crate) struct IdentityVerificationHandler< A: AuthorApi, S: StfEnclaveSigning, H: HandleState, - O: EnclaveOnChainOCallApi, + O: EnclaveOnChainOCallApi + EnclaveMetricsOCallApi, AR: AssertionLogicRepository, > where ShieldingKeyRepository: AccessKey, @@ -56,7 +56,7 @@ where S: StfEnclaveSigning, H: HandleState, H::StateT: SgxExternalitiesTrait, - O: EnclaveOnChainOCallApi, + O: EnclaveOnChainOCallApi + EnclaveMetricsOCallApi, AR: AssertionLogicRepository, { type Error = IMPError; diff --git a/tee-worker/litentry/core/stf-task/receiver/src/lib.rs b/tee-worker/litentry/core/stf-task/receiver/src/lib.rs index 8a7b431c43..141829af5c 100644 --- a/tee-worker/litentry/core/stf-task/receiver/src/lib.rs +++ b/tee-worker/litentry/core/stf-task/receiver/src/lib.rs @@ -90,7 +90,7 @@ pub struct StfTaskContext< A: AuthorApi, S: StfEnclaveSigning, H: HandleState, - O: EnclaveOnChainOCallApi, + O: EnclaveOnChainOCallApi + EnclaveMetricsOCallApi, AR: AssertionLogicRepository, > where ShieldingKeyRepository: AccessKey, @@ -111,7 +111,7 @@ impl< A: AuthorApi, S: StfEnclaveSigning, H: HandleState, - O: EnclaveOnChainOCallApi, + O: EnclaveOnChainOCallApi + EnclaveMetricsOCallApi, AR: AssertionLogicRepository, > StfTaskContext where diff --git a/tee-worker/service/src/prometheus_metrics.rs b/tee-worker/service/src/prometheus_metrics.rs index 6d1b4d950c..cdc983ceff 100644 --- a/tee-worker/service/src/prometheus_metrics.rs +++ b/tee-worker/service/src/prometheus_metrics.rs @@ -100,7 +100,12 @@ lazy_static! { static ref FAILED_VC_ISSUANCE_TASKS: Counter = register_counter!("litentry_worker_vc_failed_issuances_tasks", "Failed VC Issuance tasks") .unwrap(); - + static ref DYNAMIC_ASSERTION_SAVE_TIME: Histogram = + register_histogram!("litentry_worker_dynamic_assertion_save_time", "Time taken to save a dynamic assertion") + .unwrap(); + static ref DYNAMIC_ASSERTION_GET_TIME: Histogram = + register_histogram!("litentry_worker_dynamic_assertion_get_time", "Time taken to get a dynamic assertion") + .unwrap(); } pub async fn start_metrics_server( @@ -250,6 +255,12 @@ impl ReceiveEnclaveMetrics for EnclaveMetricsReceiver { EnclaveMetric::FailedVCIssuance => { FAILED_VC_ISSUANCE_TASKS.inc(); }, + EnclaveMetric::DynamicAssertionSaveTime(time) => { + DYNAMIC_ASSERTION_SAVE_TIME.observe(time.as_secs_f64()); + }, + EnclaveMetric::DynamicAssertionGetTime(time) => { + DYNAMIC_ASSERTION_GET_TIME.observe(time.as_secs_f64()); + }, } Ok(()) }