diff --git a/crates/phactory/api/proto/pruntime_rpc.proto b/crates/phactory/api/proto/pruntime_rpc.proto index 63ad25adf..1dfe66053 100644 --- a/crates/phactory/api/proto/pruntime_rpc.proto +++ b/crates/phactory/api/proto/pruntime_rpc.proto @@ -184,6 +184,8 @@ message PhactoryInfo { repeated string supported_attestation_methods = 28; // The number of live sidevm instances. uint32 live_sidevm_instances = 29; + // The timeout for contract query in seconds. + uint32 query_timeout = 30; } // Basic information for the initialized runtime diff --git a/crates/phactory/api/src/ecall_args.rs b/crates/phactory/api/src/ecall_args.rs index 6f3b8f23b..e09b92a76 100644 --- a/crates/phactory/api/src/ecall_args.rs +++ b/crates/phactory/api/src/ecall_args.rs @@ -48,6 +48,9 @@ pub struct InitArgs { /// The max retry times of getting the attestation report. pub ra_max_retries: u32, + + /// The timeout of a single contract query. + pub query_timeout: u64, } pub use phala_git_revision::git_revision; diff --git a/crates/phactory/src/contracts/pink.rs b/crates/phactory/src/contracts/pink.rs index a86d8baeb..2fa23641f 100644 --- a/crates/phactory/src/contracts/pink.rs +++ b/crates/phactory/src/contracts/pink.rs @@ -136,7 +136,10 @@ impl RuntimeHandle<'_> { } pub(crate) mod context { - use std::time::{Duration, Instant}; + use std::{ + sync::atomic::{AtomicU64, Ordering}, + time::{Duration, Instant}, + }; use anyhow::{anyhow, Result}; use phala_types::{wrap_content_to_sign, AttestationProvider, SignedContentType}; @@ -152,6 +155,8 @@ pub(crate) mod context { environmental::environmental!(exec_context: trait GetContext); + static MAX_QUERY_TIME: AtomicU64 = AtomicU64::new(10); + pub trait GetContext { fn chain_storage(&self) -> &ChainStorage; fn exec_context(&self) -> ExecContext; @@ -314,9 +319,17 @@ pub(crate) mod context { time_remaining().as_millis() as u64 } + pub fn set_query_time_limit(seconds: u64) { + MAX_QUERY_TIME.store(seconds, Ordering::Relaxed); + } + + pub fn query_time_limit() -> u64 { + MAX_QUERY_TIME.load(Ordering::Relaxed) + } + pub fn time_remaining() -> Duration { - const MAX_QUERY_TIME: Duration = Duration::from_secs(10); - MAX_QUERY_TIME.saturating_sub(call_elapsed()) + let limit = Duration::from_secs(query_time_limit()); + limit.saturating_sub(call_elapsed()) } pub fn sidevm_query(origin: [u8; 32], vmid: [u8; 32], payload: Vec) -> Result> { diff --git a/crates/phactory/src/lib.rs b/crates/phactory/src/lib.rs index 0427f9ca2..92901fa7a 100644 --- a/crates/phactory/src/lib.rs +++ b/crates/phactory/src/lib.rs @@ -436,11 +436,12 @@ impl Phactory { } self.can_load_chain_state = !system::gk_master_key_exists(&args.sealing_path); - self.args = Arc::new(args); - self.query_scheduler = create_query_scheduler(self.args.cores); + self.query_scheduler = create_query_scheduler(args.cores); + self.set_args(args); } pub fn set_args(&mut self, args: InitArgs) { + contracts::pink::context::set_query_time_limit(args.query_timeout); self.args = Arc::new(args); if let Some(system) = &mut self.system { system.sealing_path = self.args.sealing_path.clone(); diff --git a/crates/phactory/src/prpc_service.rs b/crates/phactory/src/prpc_service.rs index d24192248..e9d2b752e 100644 --- a/crates/phactory/src/prpc_service.rs +++ b/crates/phactory/src/prpc_service.rs @@ -163,6 +163,7 @@ impl Phactory }, supported_attestation_methods: self.platform.supported_attestation_methods(), live_sidevm_instances: sidevm::vm_count() as u32, + query_timeout: self.args.query_timeout as _, } } diff --git a/standalone/pruntime/Cargo.lock b/standalone/pruntime/Cargo.lock index abd8bafde..94fe27123 100644 --- a/standalone/pruntime/Cargo.lock +++ b/standalone/pruntime/Cargo.lock @@ -4974,7 +4974,7 @@ dependencies = [ "sp-std 8.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0)", "staging-xcm", "staging-xcm-builder", - "wasm-instrument 0.4.0", + "wasm-instrument", "wasmi", ] @@ -8256,7 +8256,7 @@ dependencies = [ [[package]] name = "sidevm-host-runtime" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "dashmap", @@ -8283,7 +8283,6 @@ dependencies = [ "tokio-rustls 0.23.4", "tracing", "trust-dns-resolver", - "wasm-instrument 0.3.0", "wasmer", "wasmer-compiler-singlepass", "wasmer-middlewares", @@ -10609,15 +10608,6 @@ dependencies = [ "leb128", ] -[[package]] -name = "wasm-instrument" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa1dafb3e60065305741e83db35c6c2584bb3725b692b5b66148a38d72ace6cd" -dependencies = [ - "parity-wasm", -] - [[package]] name = "wasm-instrument" version = "0.4.0" diff --git a/standalone/pruntime/src/main.rs b/standalone/pruntime/src/main.rs index 008d89417..630239aaf 100644 --- a/standalone/pruntime/src/main.rs +++ b/standalone/pruntime/src/main.rs @@ -95,6 +95,11 @@ struct Args { /// The max retry times of getting the attestation report. #[arg(long, default_value = "1")] ra_max_retries: u32, + + /// The timeout of a single contract query in seconds. The valid range is 5 to 600. + /// Out of range value will be clamped to the nearest bound. + #[arg(long, default_value = "10")] + query_timeout: u64, } impl Args { @@ -137,6 +142,7 @@ impl Args { no_rcu: self.no_rcu, ra_timeout: self.ra_timeout, ra_max_retries: self.ra_max_retries, + query_timeout: self.query_timeout.clamp(5, 600), } } }