diff --git a/crates/phactory/api/proto b/crates/phactory/api/proto index 21d5484f21..8c1b23f60b 160000 --- a/crates/phactory/api/proto +++ b/crates/phactory/api/proto @@ -1 +1 @@ -Subproject commit 21d5484f2126cbe0191eeae1d6a9248da57da7d5 +Subproject commit 8c1b23f60bfba5b33d11d7223dfcbe9a0ef76501 diff --git a/crates/phactory/src/contracts/pink.rs b/crates/phactory/src/contracts/pink.rs index fd383cfece..bd42478dba 100644 --- a/crates/phactory/src/contracts/pink.rs +++ b/crates/phactory/src/contracts/pink.rs @@ -19,7 +19,7 @@ use pink::{ }, local_cache::{self, StorageQuotaExceeded}, runtimes::v1::{get_runtime, using_ocalls}, - types::ExecutionMode, + types::{BlockNumber, ExecutionMode}, }; use serde::{Deserialize, Serialize}; use sidevm::service::{Command as SidevmCommand, CommandSender, Metric, SystemMessage}; @@ -861,6 +861,29 @@ impl Cluster { pub(crate) fn snapshot(&self) -> Self { self.clone() } + + pub(crate) fn upgrade_runtime(&mut self, version: (u32, u32)) { + let current = self.config.runtime_version; + info!("Try to upgrade runtime to {version:?}, current version is {current:?}"); + if version <= current { + info!("Runtime version is already {current:?}"); + return; + } + if current == (1, 0) { + // The 1.0 runtime didn't call on_genesis on cluster setup, so we need to call it + // manually to make sure the storage_versions are correct before migration. + self.default_runtime_mut().on_genesis(); + } + self.config.runtime_version = version; + self.default_runtime_mut().on_runtime_upgrade(); + info!("Runtime upgraded to {version:?}"); + } + + pub(crate) fn on_idle(&mut self, block_number: BlockNumber) { + if pink::types::ECallsAvailable::on_idle(self.config.runtime_version) { + self.default_runtime_mut().on_idle(block_number); + } + } } pub trait ClusterContainer { diff --git a/crates/phactory/src/prpc_service.rs b/crates/phactory/src/prpc_service.rs index de18f7637b..ec8afacace 100644 --- a/crates/phactory/src/prpc_service.rs +++ b/crates/phactory/src/prpc_service.rs @@ -2014,4 +2014,24 @@ impl PhactoryApi for Rpc .load_cluster_state(&req.filename) .map_err(from_debug) } + async fn try_upgrade_pink_runtime( + &mut self, + req: pb::PinkRuntimeVersion, + ) -> Result<(), prpc::server::Error> { + let version = (req.major, req.minor); + let block_number; + let mut cluster = { + let mut phactory = self.lock_phactory(true, false)?; + block_number = phactory.current_block()?.0; + let system = phactory.system()?; + let cluster = system + .contract_cluster + .as_ref() + .ok_or_else(|| from_display("Worker not in cluster"))?; + cluster.clone() + }; + cluster.upgrade_runtime(version); + cluster.on_idle(block_number); + Ok(()) + } } diff --git a/crates/phactory/src/system/mod.rs b/crates/phactory/src/system/mod.rs index c6bcde30a9..732f7d5576 100644 --- a/crates/phactory/src/system/mod.rs +++ b/crates/phactory/src/system/mod.rs @@ -14,7 +14,7 @@ use core::fmt; use phala_scheduler::RequestScheduler; use pink::{ capi::v1::ecall::{ClusterSetupConfig, ECalls}, - types::{AccountId, ECallsAvailable, ExecSideEffects, ExecutionMode, TransactionArguments}, + types::{AccountId, ExecSideEffects, ExecutionMode, TransactionArguments}, }; use runtime::BlockNumber; @@ -664,7 +664,6 @@ impl System { } fn process_contract_messages(&mut self, block: &mut BlockInfo) { - let log_handler = self.get_system_message_handler(); // Iterate over all contracts to handle their incoming commands. // // Since the wasm contracts can instantiate new contracts, it means that it will mutate the `self.contracts`. @@ -675,6 +674,7 @@ impl System { // Inner loop to handle commands. One command per iteration and apply the command side-effects to make it // availabe for next command. loop { + let log_handler = self.get_system_message_handler(); let Some(cluster) = &mut self.contract_cluster else { return; }; @@ -698,15 +698,13 @@ impl System { block, &self.egress, &self.sidevm_spawner, - log_handler.clone(), + log_handler, block.storage, ); } } if let Some(cluster) = &mut self.contract_cluster { - if ECallsAvailable::on_idle(cluster.config.runtime_version) { - cluster.runtime_mut(log_handler).on_idle(block.block_number); - } + cluster.on_idle(block.block_number); }; } @@ -1830,19 +1828,7 @@ pub(crate) fn apply_pink_events( } PinkEvent::UpgradeRuntimeTo { version } => { ensure_system!(); - info!("Try to upgrade runtime to {version:?}"); - if version <= cluster.config.runtime_version { - info!("Runtime version is already {version:?}"); - continue; - } - if cluster.config.runtime_version == (1, 0) { - // The 1.0 runtime didn't call on_genesis on cluster setup, so we need to call it - // manually to make sure the storage_versions are correct before migration. - cluster.default_runtime_mut().on_genesis(); - } - cluster.config.runtime_version = version; - cluster.default_runtime_mut().on_runtime_upgrade(); - info!("Runtime upgraded to {version:?}"); + cluster.upgrade_runtime(version); } } } diff --git a/standalone/pruntime/Cargo.lock b/standalone/pruntime/Cargo.lock index 0927d5f69a..2ef22ae779 100644 --- a/standalone/pruntime/Cargo.lock +++ b/standalone/pruntime/Cargo.lock @@ -5682,6 +5682,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2 1.0.66", "syn 1.0.109", + "template-quote", ] [[package]] @@ -5859,6 +5860,30 @@ dependencies = [ "yansi", ] +[[package]] +name = "proc-quote" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e84ab161de78c915302ca325a19bee6df272800e2ae1a43fe3ef430bab2a100" +dependencies = [ + "proc-macro-hack", + "proc-macro2 1.0.66", + "proc-quote-impl", + "quote 1.0.31", + "syn 1.0.109", +] + +[[package]] +name = "proc-quote-impl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb3ec628b063cdbcf316e06a8b8c1a541d28fa6c0a8eacd2bfb2b7f49e88aa0" +dependencies = [ + "proc-macro-hack", + "proc-macro2 1.0.66", + "quote 1.0.31", +] + [[package]] name = "prost" version = "0.9.0" @@ -8293,6 +8318,28 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "template-quote" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b774676e9c0a6ece1b3b866f2501d02ce66a8319bc5ed38a6dc2cf863f56970c" +dependencies = [ + "proc-quote", + "template-quote-impl", +] + +[[package]] +name = "template-quote-impl" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3008126541b827d5b3abaac25659be4f0c32bf956d6c0b10526ae0acf93709cb" +dependencies = [ + "proc-macro-error", + "proc-macro2 1.0.66", + "quote 1.0.31", + "syn 1.0.109", +] + [[package]] name = "tera" version = "1.16.0" @@ -8818,7 +8865,7 @@ checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", "digest 0.10.7", - "rand 0.4.6", + "rand 0.8.5", "static_assertions", ] diff --git a/standalone/pruntime/src/api_server.rs b/standalone/pruntime/src/api_server.rs index ab6efe0782..2343f0f794 100644 --- a/standalone/pruntime/src/api_server.rs +++ b/standalone/pruntime/src/api_server.rs @@ -206,6 +206,7 @@ fn rpc_type(method: &str) -> RpcType { GenerateClusterStateRequest => Private, SaveClusterState => Public, LoadClusterState => Private, + TryUpgradePinkRuntime => Private, }, } } @@ -250,6 +251,7 @@ fn default_payload_limit_for_method(method: PhactoryAPIMethod) -> ByteUnit { GenerateClusterStateRequest => 1.kibibytes(), SaveClusterState => 1.kibibytes(), LoadClusterState => 1.kibibytes(), + TryUpgradePinkRuntime => 1.kibibytes(), } }