Skip to content

Commit

Permalink
pruntime: Add RPC try_upgrade_pink_runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
kvinwang committed Sep 5, 2023
1 parent be58767 commit dcc8c27
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 22 deletions.
2 changes: 1 addition & 1 deletion crates/phactory/api/proto
Submodule proto updated 1 files
+10 −0 pruntime_rpc.proto
25 changes: 24 additions & 1 deletion crates/phactory/src/contracts/pink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand Down
20 changes: 20 additions & 0 deletions crates/phactory/src/prpc_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2014,4 +2014,24 @@ impl<Platform: pal::Platform + Serialize + DeserializeOwned> 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(())
}
}
24 changes: 5 additions & 19 deletions crates/phactory/src/system/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -664,7 +664,6 @@ impl<Platform: pal::Platform> System<Platform> {
}

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`.
Expand All @@ -675,6 +674,7 @@ impl<Platform: pal::Platform> System<Platform> {
// 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;
};
Expand All @@ -698,15 +698,13 @@ impl<Platform: pal::Platform> System<Platform> {
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);
};
}

Expand Down Expand Up @@ -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);
}
}
}
Expand Down
49 changes: 48 additions & 1 deletion standalone/pruntime/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions standalone/pruntime/src/api_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ fn rpc_type(method: &str) -> RpcType {
GenerateClusterStateRequest => Private,
SaveClusterState => Public,
LoadClusterState => Private,
TryUpgradePinkRuntime => Private,
},
}
}
Expand Down Expand Up @@ -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(),
}
}

Expand Down

0 comments on commit dcc8c27

Please sign in to comment.