diff --git a/Cargo.lock b/Cargo.lock index d51fca69df..a2a85b1740 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7774,6 +7774,7 @@ dependencies = [ "frame-system", "hex", "hex-literal", + "insta", "log", "pallet-balances", "pallet-randomness-collective-flip", @@ -11132,6 +11133,7 @@ version = "0.1.0" dependencies = [ "anyhow", "dashmap", + "derive_more 0.99.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures", "hex_fmt", "libc", diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..cd4063271d --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +.PHONY: all node pruntime e2e + +all: node pruntime e2e + +node: + cargo build --release +pruntime: + make -C standalone/pruntime +e2e: + make -C e2e/res + cd e2e && yarn build:proto + diff --git a/crates/phactory/api/build.rs b/crates/phactory/api/build.rs index c4e0e40eff..0ea1b05cb1 100644 --- a/crates/phactory/api/build.rs +++ b/crates/phactory/api/build.rs @@ -37,6 +37,9 @@ fn main() { "MemoryUsage", "GatekeeperStatus", "SystemInfo", + "ContractInfo", + "SidevmInfo", + "ClusterInfo", ] { builder = builder.type_attribute( r#type, diff --git a/crates/phactory/api/proto b/crates/phactory/api/proto index f85db78428..6dfdacbf95 160000 --- a/crates/phactory/api/proto +++ b/crates/phactory/api/proto @@ -1 +1 @@ -Subproject commit f85db78428e68e2039818dbfc8c42d1989819681 +Subproject commit 6dfdacbf95e71dec63763a0088e7cbe22c385d8e diff --git a/crates/phactory/src/bin_api_service.rs b/crates/phactory/src/bin_api_service.rs index 592fb6ad9b..b475e207bb 100644 --- a/crates/phactory/src/bin_api_service.rs +++ b/crates/phactory/src/bin_api_service.rs @@ -4,10 +4,6 @@ use super::*; // For bin_api impl Phactory { - pub fn getinfo(&self) -> String { - serde_json::to_string_pretty(&self.get_info()).unwrap_or_default() - } - pub fn sign_http_response(&self, body: &[u8]) -> Option { self.system.as_ref().map(|state| { let bytes = wrap_content_to_sign(body, SignedContentType::RpcResponse); diff --git a/crates/phactory/src/contracts/pink.rs b/crates/phactory/src/contracts/pink.rs index 19ef76de13..d8badf730b 100644 --- a/crates/phactory/src/contracts/pink.rs +++ b/crates/phactory/src/contracts/pink.rs @@ -113,7 +113,7 @@ impl Pink { Query::InkMessage(input_data) => { let _guard = context .query_scheduler - .acquire(self.id(), 1) + .acquire(self.id(), context.weight) .await .or(Err(QueryError::ServiceUnavailable))?; @@ -361,6 +361,10 @@ pub mod cluster { pub fn remove_cluster(&mut self, cluster_id: &ContractClusterId) -> Option { self.clusters.remove(cluster_id) } + + pub fn iter(&self) -> impl Iterator { + self.clusters.iter() + } } #[derive(Serialize, Deserialize, Default)] diff --git a/crates/phactory/src/contracts/support.rs b/crates/phactory/src/contracts/support.rs index 3d586c780e..d29d029db8 100644 --- a/crates/phactory/src/contracts/support.rs +++ b/crates/phactory/src/contracts/support.rs @@ -8,17 +8,19 @@ use phala_mq::{traits::MessageChannel, SignedMessageChannel}; use phala_scheduler::RequestScheduler; use runtime::BlockNumber; use sidevm::{ - service::{CommandSender, ExitReason}, + service::{Command as SidevmCommand, CommandSender, ExitReason}, OcallAborted, VmId, }; use super::pink::cluster::ClusterKeeper; use crate::{ + hex, secret_channel::{KeyPair, SecretMessageChannel, SecretReceiver}, system::{TransactionError, TransactionResult}, types::BlockInfo, - ContractId, + ContractId, H256, }; +use phactory_api::prpc as pb; use phala_serde_more as more; @@ -44,6 +46,7 @@ pub struct QueryContext { pub sidevm_handle: Option, pub log_handler: Option, pub query_scheduler: RequestScheduler, + pub weight: u32, } pub(crate) struct RawData(Vec); @@ -103,6 +106,8 @@ impl<'de> Deserialize<'de> for SidevmHandle { #[derive(Serialize, Deserialize)] struct SidevmInfo { code: Vec, + code_hash: H256, + start_time: String, auto_restart: bool, handle: Arc>, } @@ -118,6 +123,8 @@ pub struct FatContract { cluster_id: phala_mq::ContractClusterId, contract_id: phala_mq::ContractId, sidevm_info: Option, + weight: u32, + code_hash: Option, } impl FatContract { @@ -128,6 +135,7 @@ impl FatContract { ecdh_key: KeyPair, cluster_id: phala_mq::ContractClusterId, contract_id: phala_mq::ContractId, + code_hash: Option, ) -> Self { FatContract { contract: contract.into(), @@ -137,6 +145,8 @@ impl FatContract { cluster_id, contract_id, sidevm_info: None, + weight: 0, + code_hash, } } @@ -230,9 +240,14 @@ impl FatContract { bail!("Sidevm can only be started once"); } } - let handle = do_start_sidevm(spawner, &code, self.contract_id.0)?; + let handle = do_start_sidevm(spawner, &code, self.contract_id.0, self.weight)?; + + let code_hash = sp_core::blake2_256(&code).into(); + let start_time = chrono::Utc::now().to_rfc3339(); self.sidevm_info = Some(SidevmInfo { code, + code_hash, + start_time, handle, auto_restart, }); @@ -261,7 +276,8 @@ impl FatContract { if !need_restart { return Ok(()); } - do_start_sidevm(spawner, &sidevm_info.code, self.contract_id.0)? + sidevm_info.start_time = chrono::Utc::now().to_rfc3339(); + do_start_sidevm(spawner, &sidevm_info.code, self.contract_id.0, self.weight)? } else { return Ok(()); }; @@ -271,7 +287,7 @@ impl FatContract { Ok(()) } - pub(crate) fn push_message_to_sidevm(&self, message: sidevm::service::Command) -> Result<()> { + pub(crate) fn push_message_to_sidevm(&self, message: SidevmCommand) -> Result<()> { let handle = self .sidevm_info .as_ref() @@ -319,7 +335,7 @@ impl FatContract { SidevmHandle::Terminated(_) => {} SidevmHandle::Running(tx) => { spawner.spawn(async move { - if let Err(err) = tx.send(sidevm::service::Command::Stop).await { + if let Err(err) = tx.send(SidevmCommand::Stop).await { error!("Failed to send stop command to sidevm: {}", err); } }); @@ -327,12 +343,53 @@ impl FatContract { } } } + + pub fn set_weight(&mut self, weight: u32) { + self.weight = weight; + info!("Updated weight for contarct {:?} to {}", self.id(), weight); + if let Some(SidevmHandle::Running(tx)) = self.sidevm_handle() { + if let Err(_) = tx.try_send(SidevmCommand::UpdateWeight(weight)) { + error!("Failed to update weight for sidevm, maybe it has crashed"); + } + } + } + pub fn weight(&self) -> u32 { + self.weight + } + + pub fn info(&self) -> pb::ContractInfo { + pb::ContractInfo { + id: hex(&self.contract_id), + weight: self.weight, + code_hash: self.code_hash.as_ref().map(hex).unwrap_or_default(), + sidevm: self.sidevm_info.as_ref().map(|info| { + let handle = info.handle.lock().unwrap().clone(); + let start_time = info.start_time.clone(); + let code_hash = hex(&info.code_hash); + match handle { + SidevmHandle::Running(_) => pb::SidevmInfo { + state: "running".into(), + code_hash, + start_time, + ..Default::default() + }, + SidevmHandle::Terminated(reason) => pb::SidevmInfo { + state: "stopped".into(), + code_hash, + start_time, + stop_reason: format!("{}", reason), + }, + } + }), + } + } } fn do_start_sidevm( spawner: &sidevm::service::Spawner, code: &[u8], id: VmId, + weight: u32, ) -> Result>> { let max_memory_pages: u32 = 1024; // 64MB let gas_per_breath = 50_000_000_000_u64; // about 20 ms bench @@ -342,7 +399,7 @@ fn do_start_sidevm( id, gas_per_breath, local_cache_ops(), - 1, // TODO: set actual weight + weight, )?; let handle = Arc::new(Mutex::new(SidevmHandle::Running(sender))); let cloned_handle = handle.clone(); diff --git a/crates/phactory/src/contracts/support/keeper.rs b/crates/phactory/src/contracts/support/keeper.rs index ff24b5482e..2603b25b54 100644 --- a/crates/phactory/src/contracts/support/keeper.rs +++ b/crates/phactory/src/contracts/support/keeper.rs @@ -120,4 +120,8 @@ impl ContractsKeeper { pub fn remove(&mut self, id: &ContractId) -> Option { self.0.remove(id) } + + pub fn iter(&self) -> impl Iterator { + self.0.iter() + } } diff --git a/crates/phactory/src/lib.rs b/crates/phactory/src/lib.rs index 70b89cd193..c3a653dcb8 100644 --- a/crates/phactory/src/lib.rs +++ b/crates/phactory/src/lib.rs @@ -662,3 +662,7 @@ fn error_msg(msg: &str) -> Value { fn derive_key_for_checkpoint(identity_key: &[u8]) -> [u8; 16] { sp_core::blake2_128(&(identity_key, b"/checkpoint").encode()) } + +fn hex(data: impl AsRef<[u8]>) -> String { + format!("0x{}", hex_fmt::HexFmt(data)) +} diff --git a/crates/phactory/src/prpc_service.rs b/crates/phactory/src/prpc_service.rs index 255ec35768..b0a2b1d60a 100644 --- a/crates/phactory/src/prpc_service.rs +++ b/crates/phactory/src/prpc_service.rs @@ -4,6 +4,7 @@ use std::str::FromStr; use std::sync::{Arc, Mutex, MutexGuard}; use crate::benchmark::Flags; +use crate::hex; use crate::system::{chain_state, System}; use super::*; @@ -757,6 +758,65 @@ impl Phactory .encode(); Ok(signature) } + + pub fn get_contract_info( + &mut self, + contract_ids: &[String], + ) -> RpcResult { + // TODO: use `let else` + let system = match &self.system { + None => return Ok(Default::default()), + Some(system) => system, + }; + let contracts = if contract_ids.is_empty() { + system + .contracts + .iter() + .map(|(_, contract)| contract.info()) + .collect() + } else { + let mut contracts = vec![]; + for id in contract_ids.iter() { + let raw: [u8; 32] = try_decode_hex(&id) + .or(Err(from_display("Invalid contract id")))? + .try_into() + .or(Err(from_display("Invalid contract id")))?; + let contract = system.contracts.get(&raw.into()); + // TODO: use `let else`. + let contract = match contract { + None => continue, + Some(contract) => contract, + }; + contracts.push(contract.info()); + } + contracts + }; + Ok(pb::GetContractInfoResponse { contracts }) + } + + pub fn get_cluster_info(&self) -> RpcResult { + // TODO: use `let else`. + let system = match &self.system { + None => return Ok(Default::default()), + Some(system) => system, + }; + let clusters = system + .contract_clusters + .iter() + .map(|(id, cluster)| { + let contracts = cluster.iter_contracts().map(hex).collect(); + let ver = cluster.config.version; + let version = format!("{}.{}", ver.0, ver.1); + pb::ClusterInfo { + id: hex(id), + state_root: hex(cluster.storage.root()), + contracts, + version, + } + }) + .collect(); + Ok(pb::GetClusterInfoResponse { clusters }) + } } #[derive(Clone)] @@ -1323,4 +1383,22 @@ impl PhactoryApi for Rpc headers, }) } + + async fn get_contract_info( + &mut self, + request: pb::GetContractInfoRequest, + ) -> Result { + self.lock_phactory().get_contract_info(&request.contract_ids) + } + + async fn get_cluster_info( + &mut self, + _request: (), + ) -> Result { + self.lock_phactory().get_cluster_info() + } +} + +fn try_decode_hex(hex_str: &str) -> Result, hex::FromHexError> { + hex::decode(hex_str.strip_prefix("0x").unwrap_or(hex_str)) } diff --git a/crates/phactory/src/system/mod.rs b/crates/phactory/src/system/mod.rs index ee7be11cc0..4304899a7c 100644 --- a/crates/phactory/src/system/mod.rs +++ b/crates/phactory/src/system/mod.rs @@ -57,7 +57,7 @@ use sidevm::service::{Command as SidevmCommand, CommandSender, Report, Spawner, use sp_core::{hashing::blake2_256, sr25519, Pair, U256}; use sp_io; -use pink::runtime::{PinkEvent, HookPoint}; +use pink::runtime::{HookPoint, PinkEvent}; use std::cell::Cell; use std::convert::TryFrom; use std::future::Future; @@ -637,6 +637,7 @@ impl System { .storage .snapshot(); let sidevm_handle = contract.sidevm_handle(); + let weight = contract.weight(); let contract = contract.snapshot_for_query(); let mut context = contracts::QueryContext { block_number: self.block_number, @@ -645,6 +646,7 @@ impl System { sidevm_handle, log_handler: self.get_system_message_handler(&cluster_id), query_scheduler, + weight, }; let origin = origin.cloned(); Ok(async move { @@ -1703,10 +1705,12 @@ fn apply_instantiating_events( .derive_ecdh_key() .expect("Derive ecdh_key should not fail"); let id = pink.id(); + let code_hash = pink.instance.code_hash(&cluster.storage); let result = install_contract( contracts, id, pink, + code_hash, contract_key.clone(), ecdh_key.clone(), block, @@ -1758,6 +1762,19 @@ pub(crate) fn apply_pink_events( } }}; } + + let event_name = event.name(); + macro_rules! ensure_system { + () => { + if Some(&origin) != cluster.system_contract().as_ref() { + error!( + "Unpermitted operation from {:?}, operation={:?}", + &origin, &event_name + ); + continue; + } + }; + } match event { PinkEvent::Message(message) => { let contract = get_contract!(&origin); @@ -1776,13 +1793,7 @@ pub(crate) fn apply_pink_events( contract: target_contract, selector, } => { - if Some(&origin) != cluster.system_contract().as_ref() { - error!( - "Failed to set hook for {:?}, requested by {:?}: permission denied", - target_contract, origin - ); - continue; - } + ensure_system!(); let contract = get_contract!(&target_contract); match hook { HookPoint::OnBlockEnd => { @@ -1794,11 +1805,8 @@ pub(crate) fn apply_pink_events( contract: target_contract, code_hash, } => { + ensure_system!(); let vmid = sidevm::ShortId(target_contract.as_ref()); - if Some(&origin) != cluster.system_contract().as_ref() { - error!(target: "sidevm", "[{vmid}] Start sidevm failed from {}: permission denied", origin); - continue; - } let target_contract = get_contract!(&target_contract); let code_hash = code_hash.into(); let wasm_code = match cluster.get_resource(ResourceType::SidevmCode, &code_hash) { @@ -1834,24 +1842,23 @@ pub(crate) fn apply_pink_events( PinkEvent::ForceStopSidevm { contract: target_contract, } => { + ensure_system!(); let vmid = sidevm::ShortId(target_contract.as_ref()); - if Some(&origin) != cluster.system_contract().as_ref() { - error!(target: "sidevm", "[{vmid}] Stop sidevm failed from ({}): permission denied", origin); - continue; - } let contract = get_contract!(&origin); if let Err(err) = contract.push_message_to_sidevm(SidevmCommand::Stop) { error!(target: "sidevm", "[{vmid}] Push message to sidevm failed: {:?}", err); } } PinkEvent::SetLogHandler(handler) => { - if Some(&origin) != cluster.system_contract().as_ref() { - error!("Set logger failed, bad origin: {:?}", origin); - continue; - } + ensure_system!(); info!("Set logger for {:?} to {:?}", cluster_id, handler); cluster.config.log_handler = Some(handler.convert_to()); } + PinkEvent::SetContractWeight { contract, weight } => { + ensure_system!(); + let contract = get_contract!(&contract); + contract.set_weight(weight); + } } } } @@ -1883,6 +1890,7 @@ pub fn install_contract( contracts: &mut ContractsKeeper, contract_id: phala_mq::ContractId, contract: impl Into, + code_hash: Option, contract_key: sr25519::Pair, ecdh_key: EcdhKey, block: &mut BlockInfo, @@ -1907,6 +1915,7 @@ pub fn install_contract( ecdh_key.clone(), cluster_id, contract_id, + code_hash, ); contracts.insert(wrapped); Ok(()) diff --git a/crates/phala-scheduler/src/request_scheduler.rs b/crates/phala-scheduler/src/request_scheduler.rs index 36f5753a1b..dab0701cbf 100644 --- a/crates/phala-scheduler/src/request_scheduler.rs +++ b/crates/phala-scheduler/src/request_scheduler.rs @@ -96,9 +96,11 @@ pub struct ServingGuard { impl Drop for ServingGuard { fn drop(&mut self) { - let actual_cost = self - .actual_cost - .unwrap_or_else(|| self.start_time.elapsed().as_micros() as VirtualTime); + let actual_cost = self.actual_cost.unwrap_or_else(|| { + let cost = self.start_time.elapsed().as_nanos() as VirtualTime; + // Scale it in order to avoid underflow while dividing the cost by the weight. + cost << 32 + }); self.queue .inner .lock() @@ -150,7 +152,7 @@ impl SchedulerInner { }); let start_tag = self.virtual_time.max(flow.previous_finish_tag); - let cost = flow.average_cost / weight as VirtualTime; + let cost = flow.average_cost / weight.max(1) as VirtualTime; let cost = cost.max(1); let finish_tag = start_tag + cost; flow.previous_finish_tag = finish_tag; diff --git a/crates/phala-scheduler/src/task_scheduler.rs b/crates/phala-scheduler/src/task_scheduler.rs index 49331e07eb..6674aacb02 100644 --- a/crates/phala-scheduler/src/task_scheduler.rs +++ b/crates/phala-scheduler/src/task_scheduler.rs @@ -201,11 +201,13 @@ impl SchedulerInner { impl Drop for RunningGuard { fn drop(&mut self) { if let Some(inner) = self.queue.upgrade() { - let actual_cost = self - .actual_cost - .unwrap_or_else(|| self.start_time.elapsed().as_nanos() as VirtualTime); + let actual_cost = self.actual_cost.unwrap_or_else(|| { + let cost = self.start_time.elapsed().as_nanos() as VirtualTime; + // Scale it in order to avoid underflow while dividing the cost by the weight. + cost << 32 + }); let vruntime = actual_cost / self.weight.max(1) as VirtualTime; - inner.lock().unwrap().park(&self.task_id, vruntime); + inner.lock().unwrap().park(&self.task_id, vruntime.max(1)); } } } diff --git a/crates/pink-libs/system/lib.rs b/crates/pink-libs/system/lib.rs index 6d269de697..2f53926b1f 100755 --- a/crates/pink-libs/system/lib.rs +++ b/crates/pink-libs/system/lib.rs @@ -11,8 +11,8 @@ mod system { use super::pink; use alloc::string::String; use ink_storage::{traits::SpreadAllocate, Mapping}; - use pink::system::{Error, Result}; - use pink::{PinkEnvironment, HookPoint}; + use pink::system::{ContractDeposit, ContractDepositRef, Error, Result}; + use pink::{HookPoint, PinkEnvironment}; /// Pink's system contract. #[ink(storage)] @@ -53,6 +53,15 @@ mod system { fn ensure_owner_or_admin(&self) -> Result { self.ensure_owner().or_else(|_| self.ensure_admin()) } + + fn ensure_pallet(&self) -> Result { + let caller = self.env().caller(); + if pink::predefined_accounts::is_pallet(&caller) { + Ok(caller) + } else { + Err(Error::BadOrigin) + } + } } impl pink::system::System for System { @@ -101,16 +110,30 @@ mod system { } #[ink(message)] - fn set_hook( - &mut self, - hook: HookPoint, - contract: AccountId, - selector: u32, - ) -> Result<()> { + fn set_hook(&mut self, hook: HookPoint, contract: AccountId, selector: u32) -> Result<()> { self.ensure_admin()?; pink::set_hook(hook, contract, selector); Ok(()) } + + #[ink(message)] + fn set_contract_weight(&self, contract_id: AccountId, weight: u32) -> Result<()> { + self.ensure_admin()?; + pink::set_contract_weight(contract_id, weight); + Ok(()) + } + } + + impl ContractDeposit for System { + #[ink(message)] + fn change_deposit(&mut self, contract_id: AccountId, deposit: Balance) -> Result<()> { + self.ensure_pallet()?; + let flags = ink_env::CallFlags::default().set_allow_reentry(true); + match ContractDepositRef::instance_with_call_flags(flags) { + Some(mut driver) => driver.change_deposit(contract_id, deposit), + None => Ok(()), + } + } } #[cfg(test)] diff --git a/crates/pink/pink-extension/macro/src/driver_system.rs b/crates/pink/pink-extension/macro/src/driver_system.rs index c5e3d508c5..57ca75b777 100644 --- a/crates/pink/pink-extension/macro/src/driver_system.rs +++ b/crates/pink/pink-extension/macro/src/driver_system.rs @@ -33,7 +33,7 @@ fn patch_or_err( ); let impl_type = Ident::new(&format!("{trait_name}Ref"), Span::call_site()); - let crate_pink_extension = crate::find_crate_name("pink-extension")?; + let crate_pink = crate::find_crate_name("pink-extension")?; let crate_ink_lang = crate::find_crate_name("ink_lang")?; let crate_ink_env = crate::find_crate_name("ink_env")?; @@ -41,6 +41,7 @@ fn patch_or_err( let mut associated_types_v = vec![]; let mut method_sigs = vec![]; let mut method_forward_calls = vec![]; + let mut call_fns = vec![]; for item in the_trait.items.iter() { if let syn::TraitItem::Method(method) = item { @@ -73,28 +74,57 @@ fn patch_or_err( #method_ident(#(#args),*) } }); + call_fns.push({ + match method.sig.inputs.first() { + Some(FnArg::Receiver(receiver)) => { + if receiver.mutability.is_some() { + Ident::new("call_mut", Span::call_site()) + } else { + Ident::new("call", Span::call_site()) + } + } + _ => { + return Err(syn::Error::new( + method.sig.ident.span(), + "First arg must be self", + )) + } + } + }); } } let fn_instance = match interface { InterfaceType::System => quote! { pub fn instance() -> Self { + Self::instance_with_call_flags(CallFlags::default()) + } + pub fn instance_with_call_flags(call_flags: CallFlags) -> Self { #[cfg(feature = "std")] if MOCK.with(|x| { x.borrow_mut().is_some() }) { return Self::Mock; } - Self::Instance(#crate_pink_extension::ext().system_contract_id()) + Self::Instance { + address: #crate_pink::ext().system_contract_id(), + call_flags, + } } }, InterfaceType::Driver => { let driver_name = proc_macro2::Literal::string(&trait_name); quote! { pub fn instance() -> Option { + Self::instance_with_call_flags(CallFlags::default()) + } + pub fn instance_with_call_flags(flags: CallFlags) -> Option { #[cfg(feature = "std")] if MOCK.with(|x| { x.borrow_mut().is_some() }) { return Some(Self::Mock); } - let system = #crate_pink_extension::system::SystemRef::instance(); - Some(Self::Instance(system.get_driver(#driver_name.into())?)) + let system = #crate_pink::system::SystemRef::instance_with_call_flags(flags.clone()); + Some(Self::Instance { + address: system.get_driver(#driver_name.into())?, + call_flags: flags, + }) } } } @@ -106,14 +136,18 @@ fn patch_or_err( pub use #trait_impl_mod::#impl_type; mod #trait_impl_mod { use super::*; - use #crate_pink_extension::PinkEnvironment; + use #crate_pink::PinkEnvironment; use #crate_ink_lang::{codegen::TraitCallForwarder, reflect::TraitDefinitionRegistry}; use #crate_ink_env::call::FromAccountId; + use #crate_ink_env::CallFlags; type TraitInfo = as #trait_ident>::__ink_TraitInfo; type Forwarder = ::Forwarder; pub enum #impl_type { - Instance(AccountId), + Instance { + address: AccountId, + call_flags: CallFlags, + }, #[cfg(feature = "std")] Mock, } @@ -145,15 +179,27 @@ fn patch_or_err( }); } + pub fn set_call_flags(&mut self, flags: CallFlags) { + if let Self::Instance { call_flags, .. } = self { + *call_flags = flags; + } + } + #fn_instance } impl #impl_type { #(pub #method_sigs { match self { - #impl_type::Instance(address) => { + #impl_type::Instance { address, call_flags } => { + use #crate_ink_lang::codegen::TraitCallBuilder; let mut forwarder = Forwarder::from_account_id(*address); - forwarder.#method_forward_calls + forwarder + .#call_fns() + .#method_forward_calls + .call_flags(call_flags.clone()) + .fire() + .expect("Failed to forword call") } #[cfg(feature = "std")] #impl_type::Mock => { diff --git a/crates/pink/pink-extension/macro/src/snapshots/pink_extension_macro__driver_system__tests__show_patch_result.snap b/crates/pink/pink-extension/macro/src/snapshots/pink_extension_macro__driver_system__tests__show_patch_result.snap index f5deb8aee8..12bd296883 100644 --- a/crates/pink/pink-extension/macro/src/snapshots/pink_extension_macro__driver_system__tests__show_patch_result.snap +++ b/crates/pink/pink-extension/macro/src/snapshots/pink_extension_macro__driver_system__tests__show_patch_result.snap @@ -1,6 +1,6 @@ --- source: crates/pink/pink-extension/macro/src/driver_system.rs -assertion_line: 204 +assertion_line: 250 expression: "rustfmt_snippet::rustfmt_token_stream(&stream).unwrap()" --- #[ink::trait_definition(namespace = "pink_system")] @@ -16,12 +16,16 @@ pub use _pink_system_impl::SystemRef; mod _pink_system_impl { use super::*; use ink_env::call::FromAccountId; + use ink_env::CallFlags; use ink_lang::{codegen::TraitCallForwarder, reflect::TraitDefinitionRegistry}; use pink_extension::PinkEnvironment; type TraitInfo = as System>::__ink_TraitInfo; type Forwarder = ::Forwarder; pub enum SystemRef { - Instance(AccountId), + Instance { + address: AccountId, + call_flags: CallFlags, + }, #[cfg(feature = "std")] Mock, } @@ -43,20 +47,40 @@ mod _pink_system_impl { *x.borrow_mut() = Some((callee, Box::new(contract))); }); } + pub fn set_call_flags(&mut self, flags: CallFlags) { + if let Self::Instance { call_flags, .. } = self { + *call_flags = flags; + } + } pub fn instance() -> Self { + Self::instance_with_call_flags(CallFlags::default()) + } + pub fn instance_with_call_flags(call_flags: CallFlags) -> Self { #[cfg(feature = "std")] if MOCK.with(|x| x.borrow_mut().is_some()) { return Self::Mock; } - Self::Instance(pink_extension::ext().system_contract_id()) + Self::Instance { + address: pink_extension::ext().system_contract_id(), + call_flags, + } } } impl SystemRef { pub fn get_driver(&self, name: String) -> Option { match self { - SystemRef::Instance(address) => { + SystemRef::Instance { + address, + call_flags, + } => { + use ink_lang::codegen::TraitCallBuilder; let mut forwarder = Forwarder::from_account_id(*address); - forwarder.get_driver(name) + forwarder + .call() + .get_driver(name) + .call_flags(call_flags.clone()) + .fire() + .expect("Failed to forword call") } #[cfg(feature = "std")] SystemRef::Mock => MOCK.with(move |x| { @@ -75,9 +99,18 @@ mod _pink_system_impl { } pub fn set_driver(&self, name: String, driver: AccountId) { match self { - SystemRef::Instance(address) => { + SystemRef::Instance { + address, + call_flags, + } => { + use ink_lang::codegen::TraitCallBuilder; let mut forwarder = Forwarder::from_account_id(*address); - forwarder.set_driver(name, driver) + forwarder + .call() + .set_driver(name, driver) + .call_flags(call_flags.clone()) + .fire() + .expect("Failed to forword call") } #[cfg(feature = "std")] SystemRef::Mock => MOCK.with(move |x| { @@ -96,9 +129,18 @@ mod _pink_system_impl { } pub fn deploy_sidevm_to(&self, code_hash: Hash, contract_id: AccountId) -> Result<()> { match self { - SystemRef::Instance(address) => { + SystemRef::Instance { + address, + call_flags, + } => { + use ink_lang::codegen::TraitCallBuilder; let mut forwarder = Forwarder::from_account_id(*address); - forwarder.deploy_sidevm_to(code_hash, contract_id) + forwarder + .call() + .deploy_sidevm_to(code_hash, contract_id) + .call_flags(call_flags.clone()) + .fire() + .expect("Failed to forword call") } #[cfg(feature = "std")] SystemRef::Mock => MOCK.with(move |x| { diff --git a/crates/pink/pink-extension/src/chain_extension.rs b/crates/pink/pink-extension/src/chain_extension.rs index f6a4022747..b301448e9d 100644 --- a/crates/pink/pink-extension/src/chain_extension.rs +++ b/crates/pink/pink-extension/src/chain_extension.rs @@ -3,8 +3,8 @@ use alloc::vec::Vec; use ink::ChainExtensionInstance; use ink_lang as ink; -pub use ink_env::AccountId; pub use http_request::{HttpRequest, HttpResponse}; +pub use ink_env::AccountId; pub use signing::SigType; use crate::{EcdsaPublicKey, EcdsaSignature, Hash}; diff --git a/crates/pink/pink-extension/src/lib.rs b/crates/pink/pink-extension/src/lib.rs index 7dacd8991b..e4c7840fcc 100644 --- a/crates/pink/pink-extension/src/lib.rs +++ b/crates/pink/pink-extension/src/lib.rs @@ -3,7 +3,7 @@ extern crate alloc; use alloc::vec::Vec; -use ink_env::{emit_event, topics::state::HasRemainingTopics, AccountId, Environment, Topics}; +use ink_env::{emit_event, topics::state::HasRemainingTopics, Environment, Topics}; use ink_lang::EnvAccess; use scale::{Decode, Encode}; @@ -15,13 +15,13 @@ pub use chain_extension::pink_extension_instance as ext; pub mod logger; pub mod system; pub mod predefined_accounts { - use ink_env; + use super::AccountId; // TODO.kevin: Should move to a separate crates. Maybe after https://github.com/Phala-Network/phala-blockchain/issues/861 resolved. pub const ACCOUNT_PALLET: [u8; 32] = *b"sys::pellet\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; pub const ACCOUNT_RUNTIME: [u8; 32] = *b"sys::runtime\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; - pub fn is_pallet(account_id: &ink_env::AccountId) -> bool { + pub fn is_pallet(account_id: &AccountId) -> bool { account_id.as_ref() as &[u8] == &ACCOUNT_PALLET } @@ -36,6 +36,9 @@ pub type EcdhPublicKey = [u8; 32]; pub type Hash = [u8; 32]; pub type EcdsaPublicKey = [u8; 33]; pub type EcdsaSignature = [u8; 65]; +pub type AccountId = ::AccountId; +pub type Balance = ::Balance; +pub type BlockNumber = ::BlockNumber; /// A phala-mq message #[derive(Encode, Decode, Debug)] @@ -96,6 +99,8 @@ pub enum PinkEvent { }, /// Set the log handler contract for current cluster. SetLogHandler(AccountId), + /// Set the weight of contract used to schedule queries and sidevm vruntime + SetContractWeight { contract: AccountId, weight: u32 }, } impl PinkEvent { @@ -110,6 +115,22 @@ impl PinkEvent { PinkEvent::StopSidevm => true, PinkEvent::ForceStopSidevm { .. } => true, PinkEvent::SetLogHandler(_) => false, + PinkEvent::SetContractWeight { .. } => false, + } + } + + pub fn name(&self) -> &'static str { + match self { + PinkEvent::Message(_) => "Message", + PinkEvent::OspMessage(_) => "OspMessage", + PinkEvent::SetHook { .. } => "SetHook", + PinkEvent::DeploySidevmTo { .. } => "DeploySidevmTo", + PinkEvent::SidevmMessage(_) => "SidevmMessage", + PinkEvent::CacheOp(_) => "CacheOp", + PinkEvent::StopSidevm => "StopSidevm", + PinkEvent::ForceStopSidevm { .. } => "ForceStopSidevm", + PinkEvent::SetLogHandler(_) => "SetLogHandler", + PinkEvent::SetContractWeight { .. } => "SetContractWeight", } } } @@ -217,6 +238,11 @@ pub fn set_log_handler(contract: AccountId) { emit_event::(PinkEvent::SetLogHandler(contract)) } +/// Set the weight of contract used to schedule queries and sidevm vruntime +pub fn set_contract_weight(contract: AccountId, weight: u32) { + emit_event::(PinkEvent::SetContractWeight { contract, weight }); +} + /// Pink defined environment. Used this environment to access the fat contract runtime features. #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] diff --git a/crates/pink/pink-extension/src/system.rs b/crates/pink/pink-extension/src/system.rs index 9354d24c9a..e0d389650a 100644 --- a/crates/pink/pink-extension/src/system.rs +++ b/crates/pink/pink-extension/src/system.rs @@ -1,11 +1,10 @@ -use ink_env::AccountId; use ink_lang as ink; use pink_extension_macro as pink; use alloc::string::String; use scale::{Decode, Encode}; -use crate::Hash; +use crate::{AccountId, Balance, Hash}; /// Errors that can occur upon calling the system contract. #[derive(Debug, PartialEq, Eq, Encode, Decode)] @@ -28,31 +27,37 @@ pub trait System { #[ink(message, selector = 0x87c98a8d)] fn version(&self) -> (u16, u16); /// Grant an address the administrator role. + /// /// The caller must be the owner of the cluster. #[ink(message)] fn grant_admin(&mut self, contract_id: AccountId) -> Result<()>; /// Set a contract as a driver for `name`. + /// /// The caller must be the owner of the cluster or an administrator. #[ink(message)] fn set_driver(&mut self, name: String, contract_id: AccountId) -> Result<()>; /// Set a contract as a driver for `name`. + /// /// The caller must be the owner of the cluster or an administrator. #[ink(message)] fn get_driver(&self, name: String) -> Option; /// Deploy a sidevm instance attached to a given contract. + /// /// The caller must be an administrator. #[ink(message)] fn deploy_sidevm_to(&self, contract_id: AccountId, code_hash: Hash) -> Result<()>; /// Stop a sidevm instance attached to a given contract. + /// /// The caller must be an administrator. #[ink(message)] fn stop_sidevm_at(&self, contract_id: AccountId) -> Result<()>; /// Set block hook, such as OnBlockEnd, for given contract + /// /// The caller must be an administrator. #[ink(message)] fn set_hook( @@ -61,6 +66,12 @@ pub trait System { contract_id: AccountId, selector: u32, ) -> Result<()>; + + /// Set weight of the contract for query requests and sidevm scheduling. + /// + /// Higher weight would let the contract to get more resource. + #[ink(message)] + fn set_contract_weight(&self, contract_id: AccountId, weight: u32) -> Result<()>; } /// Driver to manage sidevm deployments. @@ -71,3 +82,13 @@ pub trait SidevmOperation { #[ink(message)] fn deploy(&self, code_hash: Hash) -> Result<()>; } + +/// Contracts receiving processing deposit events. Can be a driver and the system. +#[pink::driver] +#[ink::trait_definition] +pub trait ContractDeposit { + /// Change deposit of a contract. A driver should set the contract weight according to the + /// new deposit. + #[ink(message, selector = 0xa24bcb44)] + fn change_deposit(&mut self, contract_id: AccountId, deposit: Balance) -> Result<()>; +} diff --git a/crates/pink/src/contract.rs b/crates/pink/src/contract.rs index 4f8a7145a1..c232ea8ea2 100644 --- a/crates/pink/src/contract.rs +++ b/crates/pink/src/contract.rs @@ -279,6 +279,33 @@ impl Contract { pub fn set_on_block_end_selector(&mut self, selector: u32) { self.hooks.on_block_end = Some(selector) } + + pub fn code_hash(&self, storage: &Storage) -> Option { + #[derive(Encode, Decode)] + struct ContractInfo { + trie_id: Vec, + code_hash: Hash, + } + // The pallet-contracts doesn't export an API the get the code hash. So we dig it out from the storage. + let key = storage_map_prefix_twox_64_concat(b"Contracts", b"ContractInfoOf", &self.address); + let value = storage.get(&key)?; + let info = ContractInfo::decode(&mut &value[..]).ok()?; + Some(info.code_hash) + } +} + +/// Calculates the Substrate storage key prefix for a StorageMap +pub fn storage_map_prefix_twox_64_concat( + module: &[u8], + storage_item: &[u8], + key: &impl Encode, +) -> Vec { + let mut bytes = sp_core::twox_128(module).to_vec(); + bytes.extend(&sp_core::twox_128(storage_item)[..]); + let encoded = key.encode(); + bytes.extend(&sp_core::twox_64(&encoded)); + bytes.extend(&encoded); + bytes } pub fn transpose_contract_result(result: &ContractExecResult) -> Result<&[u8], ExecError> { diff --git a/crates/pink/src/storage.rs b/crates/pink/src/storage.rs index b61f867ae6..d39c8c7c11 100644 --- a/crates/pink/src/storage.rs +++ b/crates/pink/src/storage.rs @@ -168,6 +168,14 @@ where self.execute_with(true, None, move || crate::runtime::Pink::system_contract()) .0 } + + pub fn get(&self, key: &[u8]) -> Option> { + self.backend.storage(key).ok().flatten() + } + + pub fn root(&self) -> Hash { + *self.backend.as_trie_backend().root() + } } impl Serialize for Storage { diff --git a/crates/sidevm/host-runtime/Cargo.toml b/crates/sidevm/host-runtime/Cargo.toml index def7cb12b1..e5d2a8ee5c 100644 --- a/crates/sidevm/host-runtime/Cargo.toml +++ b/crates/sidevm/host-runtime/Cargo.toml @@ -34,3 +34,4 @@ once_cell = "1" tokio-proxy = { git = "https://github.com/Phala-Network/tokio-proxy" } page_size = "0.4.2" phala-scheduler = { path = "../../phala-scheduler" } +derive_more = "0.99.17" diff --git a/crates/sidevm/host-runtime/src/env.rs b/crates/sidevm/host-runtime/src/env.rs index 8db8089802..b9351ae92b 100644 --- a/crates/sidevm/host-runtime/src/env.rs +++ b/crates/sidevm/host-runtime/src/env.rs @@ -327,7 +327,10 @@ impl Env { } pub fn set_weight(&self, weight: u32) { - self.inner.lock().unwrap().weight = weight; + let mut inner = self.inner.lock().unwrap(); + inner.weight = weight; + let vm_id = ShortId(&inner.id); + log::debug!(target: "sidevm", "[{}] Updated weight to {}", vm_id, weight); } pub fn set_instance(&self, instance: Instance) { diff --git a/crates/sidevm/host-runtime/src/service.rs b/crates/sidevm/host-runtime/src/service.rs index f0aa4c9236..3023768f55 100644 --- a/crates/sidevm/host-runtime/src/service.rs +++ b/crates/sidevm/host-runtime/src/service.rs @@ -4,8 +4,8 @@ use crate::{ShortId, VmId}; use anyhow::{Context as _, Result}; use log::{debug, error, info, trace, warn}; use phala_scheduler::TaskScheduler; -use sidevm_env::messages::AccountId; use serde::{Deserialize, Serialize}; +use sidevm_env::messages::AccountId; use std::future::Future; use tokio::{ sync::mpsc::{channel, Receiver, Sender}, @@ -21,7 +21,7 @@ pub enum Report { VmTerminated { id: VmId, reason: ExitReason }, } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, derive_more::Display)] pub enum ExitReason { /// The program returned from `fn main`. Exited(i32), @@ -52,6 +52,8 @@ pub enum Command { payload: Vec, reply_tx: OneshotSender>, }, + // Update the task scheduling weight + UpdateWeight(u32), } pub struct ServiceRun { @@ -172,6 +174,9 @@ impl Spawner { Some(Command::PushQuery{ origin, payload, reply_tx }) => { spawn_push_msg!(env.push_query(origin, payload, reply_tx), debug, "query"); } + Some(Command::UpdateWeight(weight)) => { + env.set_weight(weight); + } } } rv = &mut wasm_run => { diff --git a/e2e/res/check_system/lib.rs b/e2e/res/check_system/lib.rs index d00b30d1e4..21fd48ab44 100755 --- a/e2e/res/check_system/lib.rs +++ b/e2e/res/check_system/lib.rs @@ -5,6 +5,7 @@ use pink_extension as pink; #[pink::contract(env = PinkEnvironment)] mod check_system { use super::pink; + use pink::system::{ContractDeposit, Result, SystemRef}; use pink::PinkEnvironment; #[ink(storage)] @@ -17,7 +18,9 @@ mod check_system { pub fn default() -> Self { let system = pink::system::SystemRef::instance(); _ = system.get_driver("NotExists".into()); - Self { on_block_end_called: false } + Self { + on_block_end_called: false, + } } #[ink(message)] @@ -39,4 +42,14 @@ mod check_system { self.on_block_end_called = true } } + + impl ContractDeposit for CheckSystem { + #[ink(message)] + fn change_deposit(&mut self, contract_id: AccountId, deposit: Balance) -> Result<()> { + const CENTS: Balance = 10_000_000_000; + let system = SystemRef::instance(); + let weight = deposit / CENTS; + system.set_contract_weight(contract_id, weight as u32) + } + } } diff --git a/e2e/res/check_system/target/ink/check_system.contract b/e2e/res/check_system/target/ink/check_system.contract index 8eb3dc6e5a..75bb38cee0 100644 --- a/e2e/res/check_system/target/ink/check_system.contract +++ b/e2e/res/check_system/target/ink/check_system.contract @@ -1 +1 @@ -{"source":{"hash":"0x4c3010265795e7e406ef4634b2477ab56abf3aeac124ddca7917d4a0abbb2a7b","language":"ink! 3.3.1","compiler":"rustc 1.65.0-nightly","wasm":"0x0061736d0100000001520c60027f7f0060037f7f7f0060000060017f0060087f7f7e7f7f7f7f7f017f60037f7f7f017f60057f7f7f7f7f017f6000017f60027f7f017f60037f7e7e017f60067f7e7f7f7f7f017f60057f7f7f7f7f0002e5010a057365616c31097365616c5f63616c6c0004057365616c30107365616c5f7365745f73746f726167650001057365616c30107365616c5f6765745f73746f726167650005057365616c30197365616c5f63616c6c5f636861696e5f657874656e73696f6e0006057365616c300a7365616c5f696e7075740000057365616c300b7365616c5f72657475726e0001057365616c300b7365616c5f63616c6c65720000057365616c300c7365616c5f616464726573730000057365616c30167365616c5f76616c75655f7472616e73666572726564000003656e76066d656d6f727902010210031211010001010107000203030809000a02000b0608017f01418080040b071102066465706c6f7900100463616c6c00170ac618112c01017f037f2002200346047f200005200020036a200120036a2d00003a0000200341016a21030c010b0b1a0b8d0101017f230041406a22022400200241286a200141186a290000370300200241206a200141106a290000370300200241186a200141086a2900003703002002420137030820022001290000370310200241386a41808001360200200241848104360234200241003602302002200241306a2000100b200241106a200228020020022802041001200241406b24000b6202017f017e230041206b22032400200129020421042003410036021820032004370310200320023a001f200341106a2003411f6a4101100c20012003290310370204200341086a20012003280218100d20002003290308370300200341206a24000b5d01037f230041106b2203240002402000280208220420026a220520044f0440200341086a20042005200028020020002802041019200328020c2002470d01200328020820012002100920002005360208200341106a24000f0b000b000b3c01017f2002200141086a28020022034b0440000b2001200320026b36020820012001280204220120026a36020420002002360204200020013602000b6c02027f027e230041206b22002400200041086a220142003703002000420037030020004110360214200020003602102000411036021c20002000411c6a1008200041106a200028021c100f2001290300210220002903002103200041206a2400410541042002200384501b0b3301017f230041106b22022400200241086a4100200120002802002000280204101920002002290308370200200241106a24000bc30502067f027e230041d0016b220024000240100e41ff01714105470d00200041808001360264200041848104360260200041e0006a101120002802644104490d00200028026028000041ed97f5dc01470d00100e41ff01714105470d00200041086a101241fc8004280200220141096a22022001490d0041fc800441808104280200200249047f410140002201417f46200141ffff0371200147720d0120014110742201418080046a22022001490d0141808104200236020020014109720520020b3602002001450d00200141086a41a880042d00003a0000200141a08004290000370000200041d8006a200041206a290300370300200041d0006a200041186a290300370300200041c8006a200041106a290300370300200041306a4200370300200041386a42003703002000200029030837034020004200370328200041e0006a200041286a413810092000419c016a42898080809001370200200041a4016a220242a780bdd6003702002000200136029801200041b8016a418080013602002000418481043602b401200041003602b00120002903602106200041b0016a2203200041f8006a101320032000290368200041f0006a2903001014210320002902b4012107200041003602c801200020073703c0012002200041c0016a101520002802c801220220002802c4014f0d0020002802c00120026a41243a00002000200241016a3602c801200041c0016a20014109100c20002802c401220520002802c8012201490d0020002802c00121022000200520016b3602c4012000200120026a3602c0012006200320022001200041c0016a1016410d710d0020002802c4012201450d000240024020002802c0012d00000e020100020b200141016b411f4d0d010b200041f8006a4200370300200041f0006a4200370300200041e8006a4200370300200042003703604100200041e0006a100a200041d0016a24000f0b000b3301017f230041106b220124002001200028020436020c20002802002001410c6a10042000200128020c100f200141106a24000b970101027f230041106b2201240020014180800136020420014184810436020020014180800136020c410f418481044100418481042001410c6a10031a2001200128020c100f2001280204411f4d0440000b200020012802002202290000370000200041086a200241086a290000370000200041106a200241106a290000370000200041186a200241186a290000370000200141106a24000b5102017f017e230041206b220224002000290204210320024100360218200220033703102001200241106a101820002002290310370204200241086a20002002280218100d2002280208200241206a24000b6402017f017e230041306b220324002000290204210420034100360218200320043703102003200237032820032001370320200341106a200341206a4110100c20002003290310370204200341086a20002003280218100d2003280208200341306a24000b0a00200120004104100c0b5e01017f230041106b220624002006200528020436020c41002000200120022003200420052802002006410c6a100021002005200628020c100f410c21052000410b4d0440200041027441cc80046a28020021050b200641106a240020050bf80902077f027e23004180026b22002400024002400240100e41ff01714105470d0020004180800136027c200041848104360278200041f8006a1011200028027c4104490d0020002802782800002201411876210220014110762104200141087621030240200141ff017122010440200141b901470440200141800147200341ff017141064772200441ff0171419d0147720d0341002101200241cf01460d020c030b200341ff017141f70147200441ff0171411b47720d0241012101200241fd01460d010c020b200341ff0171200441ff0171720d014102210120024101470d010b20004188016a420037030020004190016a420037030020004198016a420037030020004200370380012000420137037820004180800136024420004184810436024020004180800136022020004180016a41848104200041206a10022102200041406b2000280220100f2002410c4f0d00200241027441cc80046a2802000d002000280244450d00410021020240024020002802402d00000e020100020b410121020b024002400240200141016b0e020100020b100e41ff01714105470d0220004190016a420037030020004188016a420037030020004180016a420037030020004200370378200041203602442000200041f8006a2201360240200041203602202001200041206a1006200041406b2000280220100f2002027f4120210441a980042103034041002004450d011a200441016b210420032d0000210520012d00002106200141016a2101200341016a210320052006460d000b200620056b0b457241808004100a0c040b100e41ff01714105470d0120001012200041386a22014200370300200041306a22024200370300200041286a22044200370300200042003703202000412036027c2000200041206a2203360278200041203602402003200041406b22031007200041f8006a22052000280240100f200041f0006a200041186a290300370300200041e8006a200041106a290300370300200041e0006a200041086a290300370300200041c8006a4200370300200041d0006a420037030020002000290300370358200042003703402005200341381009200041d4016a220342b5d8ace305370200200041b4016a22052000290320370200200041bc016a2004290300370200200041c4016a2002290300370200200041cc016a2001290300370200200041013602b001200041e8016a418080013602002000418481043602e401200041003602e00120002903782107200041e0016a220120004190016a1013200120002903800120004188016a2903001014210620002902e4012108200041003602f801200020083703f0012003200041f0016a101520002802f801220120002802f4014f0d0120002802f00120016a41003a00002000200141016a3602f8012005200041f0016a22011018200041013602fc012001200041fc016a4104100c20002802f401220320002802f8012201490d0120002802f00121022000200320016b3602f4012000200120026a3602f0012007200620022001200041f0016a1016410d710d0120002802f4012201450d01024020002802f00122022d00000e020400020b20014101460d0120022d00014102490d030c010b100e41ff01714105460d010b000b230041206b22002400200041186a4180800136020020004184810436021420004100360210200041086a200041106a2002100b41002000280208200028020c1005000b20004180026a24000b0a00200120004120100c0b31000240200120024b200220044b720d002002200220016b2202490d00200020023602042000200120036a3602000f0b000b0b4d020041a080040b154e6f744578697374737379733a3a72756e74696d650041d080040b290100000002000000030000000400000005000000060000000700000008000000090000000c0000000b"},"contract":{"name":"check_system","version":"0.1.0","authors":["[your_name] <[your_email]>"]},"V3":{"spec":{"constructors":[{"args":[],"docs":[],"label":"default","payable":false,"selector":"0xed4b9d1b"}],"docs":[],"events":[],"messages":[{"args":[],"docs":[],"label":"on_block_end_called","mutates":false,"payable":false,"returnType":{"displayName":["bool"],"type":0},"selector":"0x80069dcf"},{"args":[],"docs":[],"label":"set_hook","mutates":false,"payable":false,"returnType":null,"selector":"0xb9f71bfd"},{"args":[],"docs":[],"label":"on_block_end","mutates":true,"payable":false,"returnType":null,"selector":"0x00000001"}]},"storage":{"struct":{"fields":[{"layout":{"cell":{"key":"0x0000000000000000000000000000000000000000000000000000000000000000","ty":0}},"name":"on_block_end_called"}]}},"types":[{"id":0,"type":{"def":{"primitive":"bool"}}}]}} \ No newline at end of file +{"source":{"hash":"0x338340f724f89e7e099c433e9430d11395529690de1ba3b2b8f9e8a9d90c13f0","language":"ink! 3.3.1","compiler":"rustc 1.65.0-nightly","wasm":"0x0061736d0100000001580d60027f7f0060037f7f7f0060017f0060000060017f017f60087f7f7e7f7f7f7f7f017f60037f7f7f017f60057f7f7f7f7f017f6000017f60027f7f017f60037f7e7e017f60077f7f7e7f7f7f7f017f60057f7f7f7f7f0002e5010a057365616c31097365616c5f63616c6c0005057365616c30107365616c5f7365745f73746f726167650001057365616c30107365616c5f6765745f73746f726167650006057365616c30197365616c5f63616c6c5f636861696e5f657874656e73696f6e0007057365616c300a7365616c5f696e7075740000057365616c300b7365616c5f72657475726e0001057365616c300b7365616c5f63616c6c65720000057365616c300c7365616c5f616464726573730000057365616c30167365616c5f76616c75655f7472616e73666572726564000003656e76066d656d6f72790201021003191801000100010101080002030202090a00040b030000040c000608017f01418080040b071102066465706c6f7900130463616c6c001b0a8f29182c01017f037f2002200346047f200005200020036a200120036a2d00003a0000200341016a21030c010b0b1a0b8d0101017f230041406a22022400200241286a200141186a290000370300200241206a200141106a290000370300200241186a200141086a2900003703002002420137030820022001290000370310200241386a41808001360200200241848104360234200241003602302002200241306a2000100b200241106a200228020020022802041001200241406b24000b6202017f017e230041206b22032400200129020421042003410036021820032004370310200320023a001f200341106a2003411f6a4101100f20012003290310370204200341086a20012003280218100e20002003290308370300200341206a24000bd50101067f230041206b22022400200241186a4180800136020020024184810436021420024100360210200241086a2107230041106b22032400200241106a220541086a28020021062005280204210402400240027f200141ff017141024604402006450d02200441003a000041010c010b2006450d01200441013a000020064101460d01200420013a000141020b210120052004360204200341086a20052001100e200328020c21012007200328020836020020072001360204200341106a24000c010b000b20002002280208200228020c100d000b0b002000200120021005000b3c01017f2002200141086a28020022034b0440000b2001200320026b36020820012001280204220120026a36020420002002360204200020013602000b5d01037f230041106b2203240002402000280208220420026a220520044f0440200341086a2004200520002802002000280204101f200328020c2002470d01200328020820012002100920002005360208200341106a24000f0b000b000b6c02027f027e230041206b22002400200041086a220142003703002000420037030020004110360214200020003602102000411036021c20002000411c6a1008200041106a200028021c10112001290300210220002903002103200041206a2400410541042002200384501b0b3301017f230041106b22022400200241086a4100200120002802002000280204101f20002002290308370200200241106a24000b0a00200041808004100a0b8c0602087f027e230041d0016b220024000240101041ff01714105470d00200041808001360264200041848104360260200041e0006a101420002802644104490d00200028026028000041ed97f5dc01470d00101041ff01714105470d002000101541fc8004280200220141096a22022001490d0041fc800441808104280200200249047f410140002201417f46200141ffff0371200147720d0120014110742201418080046a22022001490d0141808104200236020020014109720520020b3602002001450d00200141086a41a880042d00003a0000200141a0800429000037000020004190016a200041186a29030037030020004188016a200041106a29030037030020004180016a200041086a290300370300200041e8006a4200370300200041f0006a22034200370300200020002903003703782000420037036020002802202102200041286a2205200041e0006a2204413810092004200541381009200041a4016a220541a780bdd6003602002000419c016a428980808090013702002000200136029801200020023602a801200041b8016a418080013602002000418481043602b401200041003602b00120002903602108200041b0016a2204200041f8006a10162106200420002903682003290300101721072000027f200241ffff0371044041ac800421034100210120002802b401210420002802b8010c010b20002902b4012109200041003602c801200020093703c0012005200041c0016a101820002802c801220320002802c4014f0d0120002802c00120036a41243a00002000200341016a3602c801200041c0016a20014109100f20002802c401220520002802c8012201490d0120002802c001220320016a2104200520016b0b3602c401200020043602c0012002101920062008200720032001200041c0016a101a410d710d0020002802c4012201450d000240024020002802c0012d00000e020100020b200141016b411f4d0d010b200041f8006a4200370300200041f0006a4200370300200041e8006a4200370300200042003703604100200041e0006a100a200041d0016a24000f0b000b3301017f230041106b220124002001200028020436020c20002802002001410c6a10042000200128020c1011200141106a24000b9e0101027f230041106b2201240020014180800136020420014184810436020020014180800136020c410f418481044100418481042001410c6a10031a2001200128020c10112001280204411f4d0440000b200020012802002202290000370000200041086a200241086a290000370000200041106a200241106a290000370000200041186a200241186a29000037000020004100360020200141106a24000b5102017f017e230041206b220224002000290204210320024100360218200220033703102001200241106a101c20002002290310370204200241086a20002002280218100e2002280208200241206a24000b6402017f017e230041306b220324002000290204210420034100360218200320043703102003200237032820032001370320200341106a200341206a4110100f20002003290310370204200341086a20002003280218100e2003280208200341306a24000b0a00200120004104100f0b220020004115764108712000410e76410471200041077641027120004101717272720b5e01017f230041106b220724002007200628020436020c20002001200220032004200520062802002007410c6a100021002006200728020c1011410c21062000410b4d0440200041027441cc80046a28020021060b200741106a240020060b8716020b7f097e230041c0026b2200240002400240101041ff01714105470d0020004180800136027c200041848104360278200041f8006a1014200028027c22014104490d0020002802782204280000220241187621072002411076210320024108762105027f0240200241ff017122020440200241b901470440200241a201460d02200241800147200541ff017141064772200341ff0171419d0147720d044100200741cf01460d031a0c040b200541ff017141f70147200341ff0171411b4772200741fd0147720d034101210641000c020b200541ff0171200341ff0171722007410147720d024102210641000c010b200541ff017141cb0047200341ff017141cb014772200741c40047200141046b4120497272200141246b411049720d01200041b8016a200441046a220141086a290000370300200041c0016a200141106a290000370300200041c8016a200141186a290000370300200020012900003703b0012004290024210b2004412c6a290000210e230041206b22082400230041206b2205240002400240024002400240200e50450440200e4280c8afa025540d01200e4280c8afa025510d03200e4280c8afa02582210f200e4280c8afa0258021110c020b200b4280c8afa025822110200b4280c8afa02580210c0c030b0240200e79a72201411e6b220220014b0d0002402002450440413f21070c010b41c00020026b220741c0004b0d010b200541106a2102230041106b220324004280c8afa0252110024002400240200741ff0071220441c000714504402004450d0141c00020046b220141c0004b0d0242002004413f71ad220d864280c8afa0252001413f71ad8884210f4280c8afa025200d8621100c010b4280c8afa0252004413f71ad86210f420021100b200320103703002003200f3703080c010b000b2003290300210d2002200341086a2903003703082002200d370300200341106a2400200741ff004b200741c0004f720d00200541186a29030021112005290310210c42012007ad86210f03400240200e20117d200b200c54ad7d220d4200530d00200b200c7d210b200f2012842112200d50450440200d210e0c010b200b4280c8afa025822110200b4280c8afa02580201284210c0c050b2011423f86200c42018884210c200f420188210f201142018821110c000b000b000b200b4280c8afa0255a4101200f501b450440200b21100c030b4280e497d012210c428080808080808080807f211003400240200f200c7d200b201354ad7d220d4200530d00200b20137d210b20102012842112200d50450440200d210f0c010b200b4280c8afa025822110200b4280c8afa02580201284210c4200210f0c040b200c423f86201342018884211320104201882110200c420188210c0c000b000b200b200e822110200b200e80210c420121110c010b4200210f420021110b200820103703102008200c370300200841186a200f37030020082011370308200541206a24002008290300210d2000200841086a2903003703082000200d370300200841206a24004103210620002802000b2108200041286a200041c8016a2204290300370300200041206a200041c0016a2202290300370300200041186a200041b8016a2201290300370300200020002903b0013703102002420037030020044200370300200041d0016a4200370300200042003703b801200042013703b00120004180800136027c200041848104360278200041808001360230200141848104200041306a10022101200041f8006a200028023010112001410c4f0d00200141027441cc80046a2802000d00200028027c450d000240024020002802782d00000e020100020b410121090b02400240024002400240200641016b0e03020100030b101041ff01714105470d04200041306a1015200041e0016a200041c8006a290300370300200041d8016a200041406b290300370300200041d0016a200041386a290300370300200041b8016a4200370300200041c0016a22074200370300200020002903303703c801200042003703b0012000280250210a200041f8006a2202200041b0016a22014138100920012002413810092000418c026a220341c5d8efc401360200200041ec016a22052000290310370200200041f4016a200041186a290300370200200041fc016a200041206a29030037020020004184026a200041286a290300370200200020083602e8012000200a36029002200041b8026a418080013602002000418481043602b40241002106200041003602b00220002903b001210e200041b0026a2201200041c8016a10162104200120002903b8012007290300101721022000027f200a41ffff0371044041ac8004210320002802b402210520002802b8020c010b20002902b402210d200041003602602000200d3703582003200041d8006a2201101820052001101c20082001101d200028025c220120002802602206490d052000280258220320066a2105200120066b0b36029c022000200536029802200a10192004200e20022003200620004198026a101a410d710d042000200029039802370358200041d8006a101e41ff017122004103460d0420004102470d032009101241004102100c000b101041ff01714105470d03200041c8016a4200370300200041c0016a4200370300200041b8016a4200370300200042003703b0012000412036027c2000200041b0016a2206360278200041203602302006200041306a1006200041f8006a200028023010112009027f4120210441ac80042103034041002004450d011a200441016b210420032d0000210220062d00002101200641016a2106200341016a210320012002460d000b200120026b0b457210120c040b101041ff01714105470d02200041306a1015200041f0006a22084200370300200041e8006a22074200370300200041e0006a2204420037030020004200370358200041203602b4012000200041d8006a22013602b001200041203602782001200041f8006a22051007200041b0016a220120002802781011200041e0016a200041c8006a290300370300200041d8016a200041406b290300370300200041d0016a200041386a290300370300200041b8016a4200370300200041c0016a22024200370300200020002903303703c801200042003703b0012000280250210a200520014138100920012005413810092000418c026a220341b5d8ace305360200200041ec016a22052000290358370200200041f4016a2004290300370200200041fc016a200729030037020020004184026a2008290300370200200041013602e8012000200a36029002200041a0026a4180800136020020004184810436029c0241002109200041003602980220002903b001210e20004198026a2201200041c8016a10162104200120002903b8012002290300101721022000027f200a41ffff0371044041ac80042106200028029c02210320002802a0020c010b200029029c02210d200041003602b8022000200d3703b0022003200041b0026a101820002802b802220120002802b4024f0d0320002802b00220016a41003a00002000200141016a3602b8022005200041b0026a2201101c41012001101d20002802b402220120002802b8022209490d0320002802b002220620096a2103200120096b0b3602ac02200020033602a802200a10192004200e200220062009200041a8026a101a410d710d02200020002903a8023703b002200041b0026a101e41ff01714103470d030c020b101041ff01714105470d01230041206b22002400200041186a4180800136020020004184810436021420004100360210200041086a200041106a2009100b41002000280208200028020c100d000b41012000100c000b000b200041c0026a24000b0a00200120004120100f0b2601017f230041106b220224002002200036020c20012002410c6a4104100f200241106a24000b7401027f230041106b22012400200141086a2000102041032102024020012d00084101710d00410221020240024020012d00090e020201000b410321020c010b2001200010204103210220012d00004101710d004101410320012d000122004101461b410020001b21020b200141106a240020020b31000240200120024b200220044b720d002002200220016b2202490d00200020023602042000200120036a3602000f0b000b3c01017f200020012802042202047f2001200241016b36020420012001280200220141016a36020020012d00000520010b3a000120002002453a00000b0b50020041a080040b184e6f744578697374730000007379733a3a72756e74696d650041d080040b290100000002000000030000000400000005000000060000000700000008000000090000000c0000000b"},"contract":{"name":"check_system","version":"0.1.0","authors":["[your_name] <[your_email]>"]},"V3":{"spec":{"constructors":[{"args":[],"docs":[],"label":"default","payable":false,"selector":"0xed4b9d1b"}],"docs":[],"events":[],"messages":[{"args":[],"docs":[],"label":"on_block_end_called","mutates":false,"payable":false,"returnType":{"displayName":["bool"],"type":0},"selector":"0x80069dcf"},{"args":[],"docs":[],"label":"set_hook","mutates":false,"payable":false,"returnType":null,"selector":"0xb9f71bfd"},{"args":[],"docs":[],"label":"on_block_end","mutates":true,"payable":false,"returnType":null,"selector":"0x00000001"},{"args":[{"label":"contract_id","type":{"displayName":["AccountId"],"type":1}},{"label":"deposit","type":{"displayName":["Balance"],"type":4}}],"docs":[],"label":"ContractDeposit::change_deposit","mutates":true,"payable":false,"returnType":{"displayName":["Result"],"type":5},"selector":"0xa24bcb44"}]},"storage":{"struct":{"fields":[{"layout":{"cell":{"key":"0x0000000000000000000000000000000000000000000000000000000000000000","ty":0}},"name":"on_block_end_called"}]}},"types":[{"id":0,"type":{"def":{"primitive":"bool"}}},{"id":1,"type":{"def":{"composite":{"fields":[{"type":2,"typeName":"[u8; 32]"}]}},"path":["ink_env","types","AccountId"]}},{"id":2,"type":{"def":{"array":{"len":32,"type":3}}}},{"id":3,"type":{"def":{"primitive":"u8"}}},{"id":4,"type":{"def":{"primitive":"u128"}}},{"id":5,"type":{"def":{"variant":{"variants":[{"fields":[{"type":6}],"index":0,"name":"Ok"},{"fields":[{"type":7}],"index":1,"name":"Err"}]}},"params":[{"name":"T","type":6},{"name":"E","type":7}],"path":["Result"]}},{"id":6,"type":{"def":{"tuple":[]}}},{"id":7,"type":{"def":{"variant":{"variants":[{"index":0,"name":"BadOrigin"},{"index":1,"name":"DriverNotFound"}]}},"path":["pink_extension","system","Error"]}}]}} \ No newline at end of file diff --git a/e2e/res/pink_system.contract b/e2e/res/pink_system.contract index e4fe1baec7..85288a62f5 100644 --- a/e2e/res/pink_system.contract +++ b/e2e/res/pink_system.contract @@ -1 +1 @@ -{"source":{"hash":"0x4c4f85a39cdc00c4d9e80f8199f5eae06851c1f7ca9f6eff5338807ed7538815","language":"ink! 3.3.1","compiler":"rustc 1.65.0-nightly","wasm":"0x0061736d0100000001320960027f7f0060037f7f7f0060037f7f7f017f60017f0060000060017f017f60047f7f7f7f006000017f60057f7f7f7f7f0002f2010a057365616c30157365616c5f636f6e7461696e735f73746f726167650005057365616c30127365616c5f6465706f7369745f6576656e740006057365616c30107365616c5f7365745f73746f726167650001057365616c30107365616c5f6765745f73746f726167650002057365616c300a7365616c5f696e7075740000057365616c300b7365616c5f72657475726e0001057365616c30147365616c5f686173685f626c616b65325f3235360001057365616c300b7365616c5f63616c6c65720000057365616c30167365616c5f76616c75655f7472616e73666572726564000003656e76066d656d6f727902010210031d1c020200000001000200000001010003070403040001000308000000000608017f01418080040b071102066465706c6f7900190463616c6c001b0af7451c2b01017f037f2002200346047f200005200020036a200120036a2d00003a0000200341016a21030c010b0b0b3f01027f0340200245044041000f0b200241016b210220012d0000210320002d00002104200041016a2100200141016a210120032004460d000b200420036b0b4801017f230041106b22022400200242808001370204200241c4820436020020002002100c2002280208220020022802044b0440000b2001200228020020001002200241106a24000b0a00200120004120100e0b5e01017f230041306b22022400200241286a200141186a290000370300200241206a200141106a290000370300200241186a200141086a29000037030020024201370308200220012900003703102000200241106a100b200241306a24000b5e01037f230041106b2203240002402000280208220420026a220520044f0440200341086a20042005200028020020002802041020200328020c2002470d0120032802082001200210091a20002005360208200341106a24000f0b000b000ba10901087f230041206b22052400200541086a220320012802042202047f2001200241016b36020420012001280200220441016a36020020042d00000520010b3a000120032002453a00000240024020052d00084101710d00024020052d0009220241037122034103470440024002400240200341016b0e020102000b200241fc017141027621020c030b200520023a0015200541013a001420052001360210200541003b011c200541106a2005411c6a410210100d0320052f011c220241ff014d0d03200241027621020c020b200520023a0015200541013a0014200520013602102005410036021c200541106a2005411c6a410410100d02200528021c220241808004490d02200241027621020c010b200241044f0d0120012802042202410449047f4101052001200241046b36020420012001280200220241046a3602002002280000210241000b2103200520023602042005200336020020052802000d0120052802042202418080808004490d010b200128020422062002490d00024002402002450440410121030c010b20024100480d0141bc8204280200220320026a22042003490d0141c082042802002004490440200241ffff036a220441107640002203417f46200341ffff0371200347720d022003411074220320044180807c716a22042003490d0241c082042004360200200220036a22042003490d020b41bc820420043602002003450d010b2003200128020022042002100921032001200620026b3602042001200220046a360200024002402002450d004100200241076b2201200120024b1b2108200341036a417c7120036b21094100210103400240024002400240200120036a2d00002206411874411875220741004e0440200920016b4103712009417f46720d010240200120084f0d000340200120036a2204280200200441046a28020072418081828478710d012001200141086a22014b0d0a20012008490d000b0b200120024f0d040340200120036a2c00004100480d052002200141016a2201470d000b0c060b02400240200641aa80046a2d000041026b0e03030100080b200141016a220420024f0d07200320046a2c000021040240024002400240200641f0016b0e050100000002000b2007410f6a41ff017141024b200441004e720d0a20044140490d020c0a0b200441f0006a41ff01714130490d010c090b2004418f7f4a0d080b200141026a220420024f0d07200320046a2c000041bf7f4a0d07200141036a220120024f0d07200120036a2c000041bf7f4c0d030c070b200141016a220420024f0d06200320046a2c00002104024002400240200641e001470440200641ed01460d012007411f6a41ff0171410c490d022007417e71416e47200441004e720d0a20044140490d030c0a0b200441607141a07f460d020c090b200441a07f480d010c080b200441bf7f4a0d070b200141026a220120024f0d06200120036a2c000041bf7f4c0d020c060b200141016a21010c020b200141016a220120024f0d04200120036a2c000041bf7f4a0d040b200141016a21010b20012002490d000b0b2000200236020820002002360204200020033602000c030b200041003602000c020b000b200041003602000b200541206a24000b910101027f20002f01042103200041003a0004410121040240024020034101714504402000280200220028020422032002490d02200120002802002201200210091a0c010b200120034108763a0000200028020022002802042203200241016b2202490d01200141016a20002802002201200210091a0b2000200320026b3602042000200120026a360200410021040b20040bd50101067f230041206b22022400200241186a41808001360200200241c4820436021420024100360210200241086a2107230041106b22032400200241106a220541086a28020021062005280204210402400240027f200141ff017141024604402006450d02200441003a000041010c010b2006450d01200441013a000020064101460d01200420013a000141020b210120052004360204200341086a200520011015200328020c21012007200328020836020020072001360204200341106a24000c010b000b20002002280208200228020c1014000bc90101017f230041106b22022400200241808001360204200241c4820436020020024180800136020c200141c482042002410c6a100321012002200228020c101302402000027f02400240024020010e0402000001000b000b41000c010b200228020441204f044020004180023b0000200041026a200228020022012900003700002000410a6a200141086a290000370000200041126a200141106a2900003700002000411a6a200141186a2900003700000c020b41010b3a0000200041003a00010b200241106a24000b3301017f230041106b22022400200241086a4100200120002802002000280204102020002002290308370200200241106a24000b0b002000200120021005000b3c01017f2002200141086a28020022034b0440000b2001200320026b36020820012001280204220120026a36020420002002360204200020013602000b2601017f230041106b22022400200220003b010e20012002410e6a4102100e200241106a24000b6001017f230041106b2201240020004200370000200041186a4200370000200041106a4200370000200041086a420037000020014120360204200120003602002001412036020c20002001410c6a10072001200128020c1013200141106a24000b6c02027f027e230041206b22002400200041086a220142003703002000420037030020004110360214200020003602102000411036021c20002000411c6a1008200041106a200028021c10132001290300210220002903002103200041206a2400410541042002200384501b0ba10201057f230041c0016b220024000240101841ff01714105470d00200041808001360264200041c48204360260200041e0006a101a20002802644104490d00200028026028000041ed97f5dc01470d00101841ff01714105470d00200041f8006a22014200370300200041f0006a22024200370300200041e8006a2203420037030020004188016a420037030020004190016a420037030020004198016a4200370300200041a8016a4200370300200041b0016a4200370300200041b8016a4200370300200042003703602000420137038001200042023703a001200041e0006a220410172000200441e00010092100200142003703002002420037030020034200370300200042003703602000200041e0006a100d200041c0016a24000f0b000b3301017f230041106b220124002001200028020436020c20002802002001410c6a10042000200128020c1013200141106a24000bd920020a7f067e230041d0026b22002400024002400240024002400240101841ff01714105470d0020004180800136023c200041c48204360238200041386a101a2000200028023c220836024420002000280238220136024020084104490d00200128000021072000200841046b22033602442000200141046a2205360240200741187621022007411076210420074108762106027f0240024002400240024002400240200741ff0171220741e6006b0e020401000b20074127460d0220074135460d05200741d200460d04200741aa01460d01200741870147200641ff017141c9014772200441ff0171418a01472002418d014772720d0741000c060b200641ff017141e10047200441ff017141204772200241e10047200341204972720d06200041d0006a2001411b6a290000370300200041d8006a200141236a2d00003a000020002001290013370348200129000b210a2001280007210220012f0005210520012d0004210941010c050b200641ff0171411e47200441ff0171412047722002413047720d05200041a8016a200041406b100f20002802a8012202450d0520002802444120490d0520002902ac01210a20002802402201290018210e20012800142103200041d0006a200141086a290000370300200041d8006a200141106a2800003602002000200129000037034841020c040b200641ff017141c00047200441ff017141cf0147722002410a47720d04200041a8016a200041406b100f20002802a8012202450d0420002902ac01210a41030c030b200641ff0171412f47200441ff017141ca004772200241a4014720034120497272200841246b412049720d03200129000b210a2001280007210220012f0005210520012d00042109200041bb016a200141266a2d00003a0000200041b8016a2204200141236a2d00003a000020004190026a2001413b6a29000037030020004198026a200141c3006a2d00003a0000200041b0016a22062001411b6a290000370300200020012f00243b00b9012000200141c4006a3602402000200129003337038802200020012900133703a801200129002b210e20012800272103200041d8006a2004280200360200200041d0006a2006290300370300200020002903a80137034841040c020b200641ff017141a00147200441ff017141fd014772200241ea0047200341204972720d02200041d0006a2001411b6a290000370300200041d8006a200141236a2d00003a00002000200141246a36024020002001290013370348200129000b210a2001280007210220012f0005210520012d0004210941050c010b200641ff0171412c47200441ff017141eb004772200345200241dc004772720d012000200841056b220236024420052d0000200241204972200841256b410449720d012001290009210a20012800052102200041d0006a200141196a290000370300200041d8006a200141216a2800003602002000200841296b3602442000200141296a360240200020012900113703482001280025210341060b2104200041306a200041d8006a2206280200360200200041286a200041d0006a2201290300370300200041106a20004190026a2208290300370300200041186a20004198026a22072802003a000020002000290348370320200020002903880237030820064200370300200041e0006a4200370300200041e8006a42003703002000420037035020004201370348200041a8016a2001101220002d00a8010d002008200041b2016a2901003703002007200041ba016a290100370300200041a0026a200041c2016a290100370300200020002901aa013703880220002d00a901450d00200041c0016a200041a0026a290300370300200041b8016a20004198026a290300370300200041b0016a20004190026a29030037030020002000290388023703a80120002000290350220b20002903487c220c37035020002000290358220d200b200c56ad7c220b37035820002000290360220f200b200d54ad7c220d37036020002000290368200d200f54ad7c220f370368200041d8016a200141106a2206290000370300200041d0016a200141086a2208290000370300200041e0016a200141186a2207290000370300200020012900003703c801200042013703482000200c42017c220c3703502000200b200c50ad7c220c3703582000200d200b200c56ad7c220b3703602000200f200b200d54ad7c370368200041f8016a2006290000370300200041f0016a200829000037030020004180026a2007290000370300200020012900003703e801200041c8006a200041a8016a41e00010091a0240024002400240024002400240200441016b0e06050403020100060b101841ff01714105470d06200041a8016a200041c8006a101c20002d00a8010d0b200041bc016a200041286a290300370200200041c4016a200041306a2802003602002000200a3702ac01200020023602a801200020002903203702b401230041d0006b22012400200141216a200041a8016a220241186a290000370000200141196a200241106a290000370000200141116a200241086a2900003700002001200336022c200141023a000820012002290000370009200141086a101f200141d0006a24000c090b101841ff01714105470d05200041a8016a200041c8006a101c20002d00a8010d0a200041bf016a200041286a290300370000200041c7016a200041306a2d00003a00002000200a3700af01200020023600ab01200020053b00a901200020093a00a801200020002903203700b701230041d0006b22012400200141216a200041a8016a220041186a290000370000200141196a200041106a290000370000200141116a200041086a290000370000200141073a000820012000290000370009200141086a101f200141d0006a24000c090b101841ff01714105470d04200041c0026a200041306a2201280200360200200041b8026a200041286a2204290300370300200020002903203703b002200041a8016a200041c8006a101c20002d00a8010d092000419f026a2004290300370000200041a7026a20012d00003a00002000200a37008f022000200236008b02200020053b008902200020093a0088022000200029032037009702200041aa016a200041c3026a2d00003a0000200020002f00c1023b01a8012000200e3700af01200020033600ab01200041bf016a200041106a290300370000200041c7016a200041186a2d00003a0000200020002903083700b701230041d0006b22012400200141216a20004188026a220241186a290000370000200141196a200241106a290000370000200141116a200241086a290000370000200141316a200041a8016a220041086a290000370000200141396a200041106a290000370000200141c1006a200041186a290000370000200141033a00082001200229000037000920012000290000370029200141086a101f200141d0006a24000c080b101841ff01714105470d03200041c0016a22014200370300200041b8016a22034200370300200041b0016a22054200370300200042003703a80120004280800137028c02200041c482043602880220004188016a20004188026a2204100c2002200a422088a72004101d2000280290022202200028028c024b0d032000280288022002200041a8016a22021006200041c8026a2001290300370300200041c0026a2003290300370300200041b8026a2005290300370300200020002903a8013703b0022002200041b0026a101220002d00a8010d0320004190026a2201200041b2016a29010037030020004198026a2202200041ba016a290100370300200041a0026a2203200041c2016a290100370300200020002901aa0137038802200020002d00a901047f200041c1016a2003290300370000200041b9016a2002290300370000200041b1016a200129030037000020002000290388023700a90141010541000b3a00a801230041206b22022400200241186a41808001360200200241c4820436021420024100360210200241086a2106230041206b22012400200241106a220528020421032001200541086a28020022043602142001200336021002400240027f200041a8016a22002d00004504402004450d02200341003a000041010c010b2004450d01200341013a000020014101360218200041016a200141106a100c200128021421042001280210210320012802180b21002005200436020820052003360204200141086a20052000101520062001290308370300200141206a24000c010b000b41002002280208200228020c1014000b101841ff01714105470d02200041c0026a200041306a280200360200200041b8026a200041286a290300370300200020002903203703b0022000200e3703c802200020033602c402200041a8016a200041c8006a101e20002d00a801044020004188026a200041c8006a101c20002d0088020d040b0240200a422088a72201410a470d00200241a08004410a100a0d00200041c1016a200041c8026a290300370000200041b9016a200041c0026a290300370000200041083a00a801200041b1016a200041b8026a290300370000200020002903b0023700a901200041a8016a101f0b200041c0016a22034200370300200041b8016a22054200370300200041b0016a22044200370300200042003703a80120004280800137028c02200041c482043602880220004188016a20004188026a2206100c200220012006101d2000280290022201200028028c024b0d022000280288022001200041a8016a22021006200041a0026a200329030037030020004198026a200529030037030020004190026a2004290300370300200020002903a80137038802200041b0026a20004188026a100b0c050b101841ff01714105470d01200041a8016a200041c8006a101e20002d00a8010d06200041c7026a200041286a290300370000200041cf026a200041306a2d00003a00002000200a3700b702200020023600b302200020053b00b102200020093a00b002200020002903203700bf02200041c0016a22034200370300200041b8016a22054200370300200041b0016a22014200370300200042003703a80120004280800137028c02200041c4820436028802200041e8006a20004188026a2202100c200041b0026a2002100c2000280290022202200028028c024b0d012000280288022002200041a8016a22021006200041a0026a200329030037030020004198026a200529030037030020004190026a2001290300370300200020002903a80137038802200141808001360200200041c482043602ac01200041003602a801230041106b22012400200141086a200241001015200128020c21032000200128020836020020002003360204200141106a240020004188026a2000280200200028020410022002200041c8006a41e00010091a200241808004100d0c050b101841ff01714105460d020b000b410120002d0089021011000b230041206b22012400200141186a41808001360200200141c4820436021420014100360210230041206b22002400200141106a2202290204210a200041003602182000200a3703104100200041106a2203101641012003101620022000290310370204200041086a200220002802181015200141086a2000290308370300200041206a240041002001280208200128020c1014000b2002200041c8006a41e00010091a200241808004100d0b410041021011000b410120002d00a9011011000b990201047f230041e0006b2202240020021017200241d8006a22034200370300200241d0006a22044200370300200241c8006a2205420037030020024200370340200242808001370224200241c48204360220200141206a200241206a2201100c20022001100c2002280228220120022802244d044020022802202001200241406b1006200241386a2003290300370300200241306a2004290300370300200241286a2005290300370300200220022903403703200240200241206a1000417f460440200041013b00000c010b20002002290300370001200041003a0000200041196a200241186a290300370000200041116a200241106a290300370000200041096a200241086a2903003700000b200241e0006a24000f0b000b2c01017f230041106b220324002003200136020c2003410c6a20021023200220002001100e200341106a24000b7201017f230041206b22022400200210172000027f200220014120100a0440200041003a000141010c010b20002002290300370001200041196a200241186a290300370000200041116a200241106a290300370000200041096a200241086a29030037000041000b3a0000200241206a24000bba09010a7f23004190016b22012400200141086a200041c80010091a20014101360250200142808001370274200141c48204360270200141d0006a200141f0006a1023024020012802782200418180014f0d002001410036027820014180800120006b22043602742001200041c482046a220536027041aa82044110200141f0006a101d2001280278220220012802744b0d0020012802702103200141e8006a22064200370300200141e0006a4200370300200141d8006a22074200370300200142003703500240200241214f044020014188016a2208420037030020014180016a22094200370300200141f8006a220a42003703002001420037037020032002200141f0006a100620062008290300370300200141e0006a20092903003703002007200a290300370300200120012903703703500c010b200141d0006a2003200210091a0b200141003602782001200436027420012005360270200141d0006a200141f0006a100c2000200020012802786a22004b2000418180014f720d0020014180800120006b3602742001200041c482046a2202360270024002400240024002400240024002400240024020012d0008220341016b0e080102030405060708000b200041808001460d09200241003a000020014101360278200141086a410472200141f0006a10240c080b200041808001460d08200241013a000020014101360278200141086a410472200141f0006a1024200141246a2d00004504402001280278220220012802744f0d09200128027020026a41003a00002001200241016a3602780c080b2001280278220220012802744f0d08200128027020026a41013a00002001200241016a360278200141256a200141f0006a100c0c070b200041808001460d07200041c482046a41023a0000200041ffff004f0d07200241003a000120014102360278200141086a410172200141f0006a2202100c200128022c200210220c060b200041808001460d06200241033a000020014101360278200141086a410172200141f0006a2202100c200141296a2002100c0c050b200041808001460d05200241043a000020014101360278200128020c200141146a280200200141f0006a101d0c040b200041808001460d04200241053a0000024002400240200128021041016b0e020102000b200041ffff004f0d06200241003a000120014102360278200141146a2802002001411c6a280200200141f0006a2202101d200141206a280200200141286a2802002002101d0c050b200041ffff004f0d05200241013a000120014102360278200141146a2802002001411c6a280200200141f0006a2202101d2001200141206a2903003703502002200141d0006a4108100e0c040b200041ffff004f0d04200241023a000120014102360278200141146a2802002001411c6a280200200141f0006a101d0c030b200041808001460d03200241063a0000200141013602780c020b200041808001460d02200241073a000020014101360278200141086a410172200141f0006a100c0c010b200041808001460d01200241083a000020014101360278200141086a410172200141f0006a100c0b2001280278220220012802744b0d0041c4820420002001280270200210012003410546044020012802101a0b20014190016a24000f0b000b31000240200120024b200220044b720d002002200220016b2202490d00200020023602042000200120036a3602000f0b000b2d01017f2000280208220220002802044904402000200241016a360208200028020020026a20013a00000f0b000b2601017f230041106b220224002002200036020c20012002410c6a4104100e200241106a24000b550020002802002200413f4d04402001200041027410210f0b200041ffff004d04402000410274410172200110160f0b200041ffffffff034d04402000410274410272200110220f0b2001410310212000200110220b27002000280200200041086a2802002001101d2000410c6a280200200041146a2802002001101d0b0be401030041a080040b8a0150696e6b4c6f6767657201010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010041ec81040b330202020202020202020202020202020202020202020202020202020202020303030303030303030303030303030304040404040041aa82040b107068616c612e70696e6b2e6576656e74"},"contract":{"name":"pink-system","version":"0.1.0","authors":["[your_name] <[your_email]>"]},"V3":{"spec":{"constructors":[{"args":[],"docs":[],"label":"default","payable":false,"selector":"0xed4b9d1b"}],"docs":[],"events":[],"messages":[{"args":[],"docs":[],"label":"System::version","mutates":false,"payable":false,"returnType":{"displayName":[],"type":8},"selector":"0x87c98a8d"},{"args":[{"label":"contract_id","type":{"displayName":["AccountId"],"type":0}}],"docs":[],"label":"System::grant_admin","mutates":true,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0x67612061"},{"args":[{"label":"name","type":{"displayName":["String"],"type":7}},{"label":"contract_id","type":{"displayName":["AccountId"],"type":0}}],"docs":[],"label":"System::set_driver","mutates":true,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0xaa1e2030"},{"args":[{"label":"name","type":{"displayName":["String"],"type":7}}],"docs":[],"label":"System::get_driver","mutates":false,"payable":false,"returnType":{"displayName":["Option"],"type":12},"selector":"0x2740cf0a"},{"args":[{"label":"contract_id","type":{"displayName":["AccountId"],"type":0}},{"label":"code_hash","type":{"displayName":["pink","Hash"],"type":1}}],"docs":[],"label":"System::deploy_sidevm_to","mutates":false,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0x662f4aa4"},{"args":[{"label":"contract_id","type":{"displayName":["AccountId"],"type":0}}],"docs":[],"label":"System::stop_sidevm_at","mutates":false,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0x52a0fd6a"},{"args":[{"label":"hook","type":{"displayName":["HookPoint"],"type":13}},{"label":"contract","type":{"displayName":["AccountId"],"type":0}},{"label":"selector","type":{"displayName":["u32"],"type":14}}],"docs":[],"label":"System::set_hook","mutates":true,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0x352c6b5c"}]},"storage":{"struct":{"fields":[{"layout":{"cell":{"key":"0x0000000000000000000000000000000000000000000000000000000000000000","ty":0}},"name":"owner"},{"layout":{"cell":{"key":"0x0100000000000000000000000000000000000000000000000000000000000000","ty":3}},"name":"administrators"},{"layout":{"cell":{"key":"0x0200000000000000000000000000000000000000000000000000000000000000","ty":6}},"name":"drivers"}]}},"types":[{"id":0,"type":{"def":{"composite":{"fields":[{"type":1,"typeName":"[u8; 32]"}]}},"path":["ink_env","types","AccountId"]}},{"id":1,"type":{"def":{"array":{"len":32,"type":2}}}},{"id":2,"type":{"def":{"primitive":"u8"}}},{"id":3,"type":{"def":{"composite":{"fields":[{"name":"offset_key","type":5,"typeName":"Key"}]}},"params":[{"name":"K","type":0},{"name":"V","type":4}],"path":["ink_storage","lazy","mapping","Mapping"]}},{"id":4,"type":{"def":{"tuple":[]}}},{"id":5,"type":{"def":{"composite":{"fields":[{"type":1,"typeName":"[u8; 32]"}]}},"path":["ink_primitives","Key"]}},{"id":6,"type":{"def":{"composite":{"fields":[{"name":"offset_key","type":5,"typeName":"Key"}]}},"params":[{"name":"K","type":7},{"name":"V","type":0}],"path":["ink_storage","lazy","mapping","Mapping"]}},{"id":7,"type":{"def":{"primitive":"str"}}},{"id":8,"type":{"def":{"tuple":[9,9]}}},{"id":9,"type":{"def":{"primitive":"u16"}}},{"id":10,"type":{"def":{"variant":{"variants":[{"fields":[{"type":4}],"index":0,"name":"Ok"},{"fields":[{"type":11}],"index":1,"name":"Err"}]}},"params":[{"name":"T","type":4},{"name":"E","type":11}],"path":["Result"]}},{"id":11,"type":{"def":{"variant":{"variants":[{"index":0,"name":"BadOrigin"},{"index":1,"name":"DriverNotFound"}]}},"path":["pink_extension","system","Error"]}},{"id":12,"type":{"def":{"variant":{"variants":[{"index":0,"name":"None"},{"fields":[{"type":0}],"index":1,"name":"Some"}]}},"params":[{"name":"T","type":0}],"path":["Option"]}},{"id":13,"type":{"def":{"variant":{"variants":[{"index":0,"name":"OnBlockEnd"}]}},"path":["pink_extension","HookPoint"]}},{"id":14,"type":{"def":{"primitive":"u32"}}}]}} \ No newline at end of file +{"source":{"hash":"0x2ac633f3a0483ff5aeb1db745162c0dc1d0fcafa970781e5c11b408ebd62d76c","language":"ink! 3.3.1","compiler":"rustc 1.65.0-nightly","wasm":"0x0061736d0100000001640f60027f7f0060037f7f7f0060037f7f7f017f60017f0060000060017f017f60087f7f7e7f7f7f7f7f017f60047f7f7f7f0060057f7f7f7f7f017f6000017f60027f7f017f60037f7e7e017f60067f7e7f7f7f7f017f60037e7e7f0060057f7f7f7f7f0002a6020c057365616c30157365616c5f636f6e7461696e735f73746f726167650005057365616c31097365616c5f63616c6c0006057365616c30127365616c5f6465706f7369745f6576656e740007057365616c30107365616c5f7365745f73746f726167650001057365616c30107365616c5f6765745f73746f726167650002057365616c30197365616c5f63616c6c5f636861696e5f657874656e73696f6e0008057365616c300a7365616c5f696e7075740000057365616c300b7365616c5f72657475726e0001057365616c30147365616c5f686173685f626c616b65325f3235360001057365616c300b7365616c5f63616c6c65720000057365616c30167365616c5f76616c75655f7472616e73666572726564000003656e76066d656d6f7279020102100325240202000100000100020100000001000103090403040a000b00010c0000030d0e000000000608017f01418080040b071102066465706c6f79001d0463616c6c001f0ab35b242b01017f037f2002200346047f200005200020036a200120036a2d00003a0000200341016a21030c010b0b0b3f01027f0340200245044041000f0b200241016b210220012d0000210320002d00002104200041016a2100200141016a210120032004460d000b200420036b0b4c01017f230041206b22022400200241186a41808001360200200241b0830436021420024100360210200241086a200241106a2000100e20012002280208200228020c1003200241206a24000b5602017f017e230041206b220324002001290204210420034100360218200320043703102002200341106a101020012003290310370204200341086a20012003280218101a20002003290308370300200341206a24000b5e01017f230041306b22022400200241286a200141186a290000370300200241206a200141106a290000370300200241186a200141086a29000037030020024201370308200220012900003703102000200241106a100d200241306a24000b0a0020012000412010110b5e01037f230041106b2203240002402000280208220420026a220520044f0440200341086a2004200520002802002000280204102a200328020c2002470d01200328020820012002100b1a20002005360208200341106a24000f0b000b000bae0801097f230041306b22032400200341186a220520012802042202047f2001200241016b36020420012001280200220441016a36020020042d00000520010b3a000120052002453a00000240024020032d00184101710d00024020032d0019220241037122054103470440024002400240200541016b0e020102000b200241fc017141027621020c030b200320023a0025200341013a002420032001360220200341003b012c200341206a2003412c6a410210130d0320032f012c220241ff014d0d03200241027621020c020b200320023a0025200341013a0024200320013602202003410036022c200341206a2003412c6a410410130d02200328022c220241808004490d02200241027621020c010b200241044f0d01200341106a210520012802042202410449047f4101052001200241046b36020420012001280200220241046a3602002002280000210241000b2104200520023602042005200436020020032802100d0120032802142202418080808004490d010b200128020422042002490d00200341086a200241011014200328020c210a2003280208200128020022062002100b21052001200420026b3602042001200220066a360200024002402002450d004100200241076b2201200120024b1b2108200541036a417c7120056b210941002101034002400240024002400240200120056a2d00002206411874411875220741004e0440200920016b4103712009417f46720d020240200120084f0d000340200120056a2204280200200441046a28020072418081828478710d012001200141086a22014b0d0320012008490d000b0b200120024f0d050340200120056a2c00004100480d062002200141016a2201470d000b0c070b02400240200641aa80046a2d000041026b0e03040100090b200141016a220420024f0d08200420056a2c000021040240024002400240200641f0016b0e050100000002000b2007410f6a41ff017141024b200441004e720d0b20044140490d020c0b0b200441f0006a41ff01714130490d010c0a0b2004418f7f4a0d090b200141026a220420024f0d08200420056a2c000041bf7f4a0d08200141036a220120024f0d08200120056a2c000041bf7f4c0d040c080b200141016a220420024f0d07200420056a2c00002104024002400240200641e001470440200641ed01460d012007411f6a41ff0171410c490d022007417e71416e47200441004e720d0b20044140490d030c0b0b200441607141a07f460d020c0a0b200441a07f480d010c090b200441bf7f4a0d080b200141026a220120024f0d07200120056a2c000041bf7f4c0d030c070b000b200141016a21010c020b200141016a220120024f0d04200120056a2c000041bf7f4a0d040b200141016a21010b20012002490d000b0b200020023602082000200a360204200020053602000c020b200041003602000c010b200041003602000b200341306a24000b910101027f20002f01042103200041003a0004410121040240024020034101714504402000280200220028020422032002490d022001200028020022012002100b1a0c010b200120034108763a0000200028020022002802042203200241016b2202490d01200141016a200028020022012002100b1a0b2000200320026b3602042000200120026a360200410021040b20040b8b0301067f230041106b2206240002402001450440410121020c010b200141004e0440200641086a21082001417f73411f76220420016a41016b410020046b712204200149210541a88304280200210302400240027f200245044020050d0241002105200320046a22022003490d032003200241ac83042802004d0d011a200441ffff036a22022004490d032002411076220740002202417f46200241ffff0371200247720d032002411074220320074110746a22022003490d0341ac83042002360200200320046a22022003490d0320030c010b20050d0141002105200320046a22022003490d022003200241ac83042802004d0d001a200441ffff036a22022004490d022002411076220740002202417f46200241ffff0371200247720d022002411074220320074110746a22022003490d0241ac83042002360200200320046a22022003490d0220030b210541a8830420023602000c010b000b2008200136020420082005360200200628020822020d010b000b2000200136020420002002360200200641106a24000bd50101067f230041206b22022400200241186a41808001360200200241b0830436021420024100360210200241086a2107230041106b22032400200241106a220541086a28020021062005280204210402400240027f200141ff017141024604402006450d02200441003a000041010c010b2006450d01200441013a000020064101460d01200420013a000141020b210120052004360204200341086a20052001101a200328020c21012007200328020836020020072001360204200341106a24000c010b000b20002002280208200228020c1018000bdb0101017f230041106b22022400200241808001360204200241b0830436020020024180800136020c200141b083042002410c6a100421012002200228020c101702402000027f0240024002402001410c4f0d00200141027441f882046a2802000e0402000001000b000b41000c010b200228020441204f044020004180023b0000200041026a200228020022012900003700002000410a6a200141086a290000370000200041126a200141106a2900003700002000411a6a200141186a2900003700000c020b41010b3a0000200041003a00010b200241106a24000b3301017f230041106b22022400200241086a4100200120002802002000280204102a20002002290308370200200241106a24000b0b002000200120021007000b2601017f230041106b22022400200220003b010e20012002410e6a41021011200241106a24000b3c01017f2002200141086a28020022034b0440000b2001200320026b36020820012001280204220120026a36020420002002360204200020013602000b6001017f230041106b2201240020004200370000200041186a4200370000200041106a4200370000200041086a420037000020014120360204200120003602002001412036020c20002001410c6a10092001200128020c1017200141106a24000b6c02027f027e230041206b22002400200041086a220142003703002000420037030020004110360214200020003602102000411036021c20002000411c6a100a200041106a200028021c10172001290300210220002903002103200041206a2400410541042002200384501b0ba10201057f230041c0016b220024000240101c41ff01714105470d00200041808001360264200041b08304360260200041e0006a101e20002802644104490d00200028026028000041ed97f5dc01470d00101c41ff01714105470d00200041f8006a22014200370300200041f0006a22024200370300200041e8006a2203420037030020004188016a420037030020004190016a420037030020004198016a4200370300200041a8016a4200370300200041b0016a4200370300200041b8016a4200370300200042003703602000420137038001200042023703a001200041e0006a2204101b2000200441e000100b2100200142003703002002420037030020034200370300200042003703602000200041e0006a100f200041c0016a24000f0b000b3301017f230041106b220124002001200028020436020c20002802002001410c6a10062000200128020c1017200141106a24000baa30020a7f077e230041a0046b2200240002400240024002400240101c41ff01714105470d002000418080013602fc01200041b083043602f801200041f8016a101e200020002802fc01220536029c02200020002802f80122013602980220054104490d00200128000021072000200541046b220336029c022000200141046a220836029802200741187621042007411076210220074108762106027f024002400240024002400240024002400240200741ff0171220741e6006b0e020401000b20074127460d0220074135460d05200741c500460d06200741d200460d04200741aa01460d01200741a201460d07200741870147200641ff017141c9014772200241ff0171418a01472004418d014772720d0941000c080b200641ff017141e10047200241ff017141204772200441e10047200341204972720d08200041e0006a2001411b6a290000370300200041e8006a200141236a2d00003a000020002001290013370358200129000b210a2001280007210220012f0005210820012d0004210341010c070b200641ff0171411e47200241ff0171412047722004413047720d07200041a8036a20004198026a101220002802a8032202450d07200028029c024120490d0720002902ac03210a2000280298022201290018210e20012800142104200041e0006a200141086a290000370300200041e8006a200141106a2800003602002000200129000037035841020c060b200641ff017141c00047200241ff017141cf0147722004410a47720d06200041a8036a20004198026a101220002802a8032202450d0620002902ac03210a41030c050b200641ff0171412f47200241ff017141ca004772200441a4014720034120497272200541246b412049720d05200129000b210a2001280007210220012f0005210820012d00042103200041bb036a200141266a2d00003a0000200041f8026a200141c3006a2d00003a0000200041b0036a2001411b6a290000220b370300200041b8036a2205200141236a2d00003a00002000200141c4006a36029802200020012f00243b00b9032000200129003b3703f00220002001290013220c3703a803200141336a2900002110200129002b210e20012800272104200041e0006a200b370300200041e8006a20052802003602002000200c37035841040c040b200641ff017141a00147200241ff017141fd014772200441ea0047200341204972720d04200041e0006a2001411b6a290000370300200041e8006a200141236a2d00003a00002000200141246a3602980220002001290013370358200129000b210a2001280007210220012f0005210820012d0004210341050c030b200641ff0171412c47200241ff017141eb004772200345200441dc004772720d032000200541056b220236029c0220082d0000200241204972200541256b410449720d032001290009210a20012800052102200041e0006a200141196a290000370300200041e8006a200141216a2800003602002000200541296b36029c022000200141296a36029802200020012900113703582001280025210441060c020b200641ff017141ec0147200241ff0171419b0147722004411847200341204972722005417c71412446720d022001290008210a20012800042102200041e0006a200141186a290000370300200041e8006a200141206a2800003602002000200541286b36029c022000200141286a36029802200020012900103703582001280024210441070c010b200641ff017141cb0047200241ff017141cb014772200441c4004720034120497272200541246b411049720d01200128002021042001290004210a200041e0006a200141146a290000370300200041e8006a2001411c6a2800003602002000200541346b36029c022000200141346a360298022000200129000c3703582001412c6a29000021102001290024210e41080b2105200041d0006a200041e8006a2206280200360200200041c8006a200041e0006a2201290300370300200041386a200041f8026a22072903003c000020002000290358370340200020002903f00237033020064200370300200041f0006a4200370300200041f8006a42003703002000420037036020004201370358200041a8036a2001101620002d00a8030d002007200041b2036a29010037030020004180036a200041ba036a29010037030020004188036a200041c2036a290100370300200020002901aa033703f00220002d00a903450d00200041c0036a20004188036a290300370300200041b8036a20004180036a290300370300200041b0036a200041f8026a290300370300200020002903f0023703a80320002000290360220b20002903587c220d37036020002000290368220c200b200d56ad7c220b37036820002000290370220f200b200c54ad7c220c37037020002000290378200c200f54ad7c220f370378200041d8036a200141106a2206290000370300200041d0036a200141086a2207290000370300200041e0036a200141186a2209290000370300200020012900003703c803200042013703582000200d42017c220d3703602000200b200d50ad7c220d3703682000200c200b200d56ad7c220b3703702000200f200b200c54ad7c370378200041f8036a2006290000370300200041f0036a200729000037030020004180046a2009290000370300200020012900003703e803200041d8006a200041a8036a41e000100b1a02400240027f0240024002400240024002400240024002400240024002400240200541016b0e080706050403020100080b101c41ff01714105470d0f200041a8036a2201101b41002102200141aa82041020450d0d200041b0036a220241808001360200200041b083043602ac03200041003602a803200041286a200041a8036a1021200028022c2101200028022821032000200228020022053602f402200020002802ac0322063602f002200020053602d002410f200320012006200041d0026a10051a200041f0026a20002802d002101720002802f402411f4d0d0f200041e0016a220320002802f002220141086a290000370300200041e8016a2205200141106a290000370300200041f0016a2206200141186a290000370300200020012900003703d801200041206a410f41001014200028022421082000280220220141da8204290000370000200141076a41e18204290000370000200041d8036a2006290300370300200041d0036a2005290300370300200041c8036a200329030037030020024200370300200041b8036a22024200370300200020002903d8013703c003200042003703a803200041f0026a2203200041a8036a22054138100b1a200520034138100b1a200041e8036a428f808080f084d0e70a370300200041e4036a2008360200200020013602e003200041808080083602f003200041c0026a41808001360200200041b083043602bc02200041003602b80220002903a803210b200041186a200041b8026a2203200041c0036a100e2000280218200320002903b00320022903001022210320002902bc02210c200041003602d8022000200c3703d002200041ec036a200041d0026a220210232001410f2002102420002802d402220620002802d8022201490d0f20002802d00221022000200620016b3602cc022000200120026a3602c802200b200320022001200041c8026a10252201410d710d08024020002802cc022201450d000240024020002802c80222032d000022020e020100020b200141016b4120490d01200041e8026a200341016a220141186a290000370300200041e0026a200141106a290000370300200041d8026a200141086a290000370300200020012900003703d0020b200041b0026a200041e8026a290300370300200041a8026a200041e0026a290300370300200041a0026a200041d8026a290300370300200020002903d0023703980241000c0d0b410021020c0b0b101c41ff01714105470d0e200041a8036a200041d8006a102620002d00a8030d12200041bc036a200041c8006a290300370200200041c4036a200041d0006a2802003602002000200a3702ac03200020023602a803200020002903403702b403230041d0006b22012400200141216a200041a8036a220041186a290000370000200141196a200041106a290000370000200041086a290000210a200141093a0008200141116a200a3700002001200436022c20012000290000370009200141086a1028200141d0006a24000c110b101c41ff01714105470d0d200041a8036a200041d8006a102620002d00a8030d11200041bc036a200041c8006a290300370200200041c4036a200041d0006a2802003602002000200a3702ac03200020023602a803200020002903403702b403230041d0006b22012400200141216a200041a8036a220241186a290000370000200141196a200241106a290000370000200141116a200241086a2900003700002001200436022c200141023a000820012002290000370009200141086a1028200141d0006a24000c0e0b101c41ff01714105470d0c200041a8036a200041d8006a102620002d00a8030d10200041bf036a200041c8006a290300370000200041c7036a200041d0006a2d00003a00002000200a3700af03200020023600ab03200020083b00a903200020033a00a803200020002903403700b703230041d0006b22012400200141216a200041a8036a220041186a290000370000200141196a200041106a290000370000200141116a200041086a290000370000200141073a000820012000290000370009200141086a1028200141d0006a24000c0f0b101c41ff01714105470d0b200041e0026a200041d0006a2201280200360200200041d8026a200041c8006a2205290300370300200020002903403703d002200041a8036a200041d8006a102620002d00a8030d0f20004187036a20052903003700002000418f036a20012d00003a00002000200a3700f702200020023600f302200020083b00f102200020033a00f002200020002903403700ff02200041b7036a2010370000200041aa036a200041e3026a2d00003a00002000200e3700af03200020002f00e1023b01a803200020043600ab03200041c7036a200041386a2d00003a0000200020002903303700bf03230041d0006b22012400200141216a200041f0026a220241186a290000370000200141196a200241106a290000370000200141116a200241086a290000370000200141316a200041a8036a220041086a290000370000200141396a200041106a290000370000200141c1006a200041186a290000370000200141033a00082001200229000037000920012000290000370029200141086a1028200141d0006a24000c0e0b101c41ff01714105470d0a200041c0036a22014200370300200041b8036a22044200370300200041b0036a22034200370300200042003703a8032000428080013702f402200041b083043602f00220004198016a200041f0026a220510102002200a422088a72005102420002802f802220220002802f4024b0d0a20002802f0022002200041a8036a22021008200041e8026a2001290300370300200041e0026a2004290300370300200041d8026a2003290300370300200020002903a8033703d0022002200041d0026a101620002d00a8030d0a200041f8026a2201200041b2036a29010037030020004180036a2202200041ba036a29010037030020004188036a2204200041c2036a290100370300200020002901aa033703f002200020002d00a903047f200041c1036a2004290300370000200041b9036a2002290300370000200041b1036a2001290300370000200020002903f0023700a90341010541000b3a00a803230041206b22022400200241186a41808001360200200241b0830436021420024100360210200241086a2106230041206b22012400200241106a220328020421042001200341086a28020022053602142001200436021002400240027f200041a8036a22002d00004504402005450d02200441003a000041010c010b2005450d01200441013a000020014101360218200041016a200141106a1010200128021421052001280210210420012802180b21002003200536020820032004360204200141086a20032000101a20062001290308370300200141206a24000c010b000b41002002280208200228020c1018000b101c41ff01714105470d09200041e0026a200041d0006a280200360200200041d8026a200041c8006a290300370300200020002903403703d0022000200e3703e802200020043602e402200041a8036a200041d8006a102720002d00a8030440200041f0026a200041d8006a102620002d00f0020d040b0240200a422088a72201410a470d00200241a08004410a100c0d00200041c1036a200041e8026a290300370000200041b9036a200041e0026a290300370000200041083a00a803200041b1036a200041d8026a290300370000200020002903d0023700a903200041a8036a10280b200041c0036a22044200370300200041b8036a22034200370300200041b0036a22054200370300200042003703a8032000428080013702f402200041b083043602f00220004198016a200041f0026a22061010200220012006102420002802f802220120002802f4024b0d0920002802f0022001200041a8036a2202100820004188036a200429030037030020004180036a2003290300370300200041f8026a2005290300370300200020002903a8033703f002200041d0026a200041f0026a100d0c0a0b101c41ff01714105470d08200041a8036a200041d8006a102720002d00a8030d0c200041e7026a200041c8006a290300370000200041ef026a200041d0006a2d00003a00002000200a3700d702200020023600d302200020083b00d102200020033a00d002200020002903403700df02200041c0036a22044200370300200041b8036a22034200370300200041b0036a22024200370300200042003703a8032000428080013702f402200041b083043602f002200041f8006a200041f0026a22011010200041d0026a2001101020002802f802220120002802f4024b0d0820002802f0022001200041a8036a2201100820004188036a200429030037030020004180036a2003290300370300200041f8026a2002290300370300200020002903a8033703f002200241808001360200200041b083043602ac03200041003602a803200041086a20011021200041f0026a2000280208200028020c10032001200041d8006a41e000100b1a200141808004100f0c0b0b101c41ff01714105460d020c070b200141e882046a2d000021020c020b410120002d00f1021015000b230041206b22012400200141186a41808001360200200141b0830436021420014100360210230041206b22002400200141106a2202290204210a200041003602182000200a3703104100200041106a2204101941012004101920022000290310370204200041086a20022000280218101a200141086a2000290308370300200041206a240041002001280208200128020c1018000b41010b0d0220004190026a2201200041b0026a29030037030020004188026a2203200041a8026a29030037030020004180026a2205200041a0026a220629030037030020002000290398023703f8012002450d01200041d0016a2001290300220b370300200041c8016a2003290300220c370300200041c0016a2005290300220d370300200020002903f801220f3703b801200041d8036a200b370300200041d0036a200c370300200041c8036a200d370300200041b0036a4200370300200041b8036a220142003703002000200f3703c003200042003703a803200041f0026a2202200041a8036a22034138100b1a200320024138100b1a200041e8036a2010370300200041f0036a2202200a37030020004190046a220341a297ada6043602002000418c046a2004360200200041f8036a200029034037030020004180046a200041c8006a29030037030020004188046a200041d0006a2802003602002000200e3703e0032000418080800836029804200641808001360200200041b0830436029c02200041003602980220002903a803210a200041106a20004198026a2204200041c0036a100e2000280210200420002903b003200129030010222104200029029c02210b200041003602d8022000200b3703d0022003200041d0026a22011023200220011010200e20102001102920002802d402220320002802d8022201490d0220002802d00221022000200320016b3602d4022000200120026a3602d002200a200420022001200041d0026a1025410d710d0220002802d4022201450d02024020002802d00222022d00000e020200030b20014101460d0220022d0001220241024f0d020b410120021015000b200041a8036a2202200041d8006a41e000100b1a0c020b000b2002200041d8006a41e000100b1a0b200241808004100f0b410041021015000b410120002d00a9031015000b0b00200020014120100c450b3701017f230041106b22022400200241086a20014100101a200228020c21012000200228020836020020002001360204200241106a24000b5302017f017e230041206b2203240020002902042104200341003602182003200437031020012002200341106a102920002003290310370204200341086a20002003280218101a2003280208200341206a24000b0a0020012000410410110b2c01017f230041106b220324002003200136020c2003410c6a2002102d2002200020011011200341106a24000b5e01017f230041106b220624002006200528020436020c41082000200120022003200420052802002006410c6a100121002005200628020c1017410c21052000410b4d0440200041027441f882046a28020021050b200641106a240020050b990201047f230041e0006b220224002002101b200241d8006a22034200370300200241d0006a22044200370300200241c8006a2205420037030020024200370340200242808001370224200241b08304360220200141206a200241206a220110102002200110102002280228220120022802244d044020022802202001200241406b1008200241386a2003290300370300200241306a2004290300370300200241286a2005290300370300200220022903403703200240200241206a1000417f460440200041013b00000c010b20002002290300370001200041003a0000200041196a200241186a290300370000200041116a200241106a290300370000200041096a200241086a2903003700000b200241e0006a24000f0b000b7101017f230041206b220224002002101b2000027f200220011020450440200041003a000141010c010b20002002290300370001200041196a200241186a290300370000200041116a200241106a290300370000200041096a200241086a29030037000041000b3a0000200241206a24000bf209010a7f23004190016b22012400200141086a200041c800100b1a20014101360250200142808001370274200141b08304360270200141d0006a200141f0006a102d024020012802782200418180014f0d002001410036027820014180800120006b22043602742001200041b083046a220536027041ca82044110200141f0006a10242001280278220220012802744b0d0020012802702103200141e8006a22064200370300200141e0006a4200370300200141d8006a22074200370300200142003703500240200241214f044020014188016a2208420037030020014180016a22094200370300200141f8006a220a42003703002001420037037020032002200141f0006a100820062008290300370300200141e0006a20092903003703002007200a290300370300200120012903703703500c010b200141d0006a20032002100b1a0b200141003602782001200436027420012005360270200141d0006a200141f0006a10102000200020012802786a22004b2000418180014f720d0020014180800120006b3602742001200041b083046a22023602700240024002400240024002400240024002400240024020012d0008220341016b0e09010203040506070809000b200041808001460d0a200241003a000020014101360278200141086a410472200141f0006a102e0c090b200041808001460d09200241013a000020014101360278200141086a410472200141f0006a102e200141246a2d00004504402001280278220220012802744f0d0a200128027020026a41003a00002001200241016a3602780c090b2001280278220220012802744f0d09200128027020026a41013a00002001200241016a360278200141256a200141f0006a10100c080b200041808001460d08200041b083046a41023a0000200041ffff004f0d08200241003a000120014102360278200141086a410172200141f0006a22021010200128022c2002102c0c070b200041808001460d07200241033a000020014101360278200141086a410172200141f0006a22021010200141296a200210100c060b200041808001460d06200241043a000020014101360278200128020c200141146a280200200141f0006a10240c050b200041808001460d05200241053a0000024002400240200128021041016b0e020102000b200041ffff004f0d07200241003a000120014102360278200141146a2802002001411c6a280200200141f0006a22021024200141206a280200200141286a280200200210240c060b200041ffff004f0d06200241013a000120014102360278200141146a2802002001411c6a280200200141f0006a220210242001200141206a2903003703502002200141d0006a410810110c050b200041ffff004f0d05200241023a000120014102360278200141146a2802002001411c6a280200200141f0006a10240c040b200041808001460d04200241063a0000200141013602780c030b200041808001460d03200241073a000020014101360278200141086a410172200141f0006a10100c020b200041808001460d02200241083a000020014101360278200141086a410172200141f0006a10100c010b200041808001460d01200241093a000020014101360278200141086a410172200141f0006a22021010200128022c2002102c0b2001280278220220012802744b0d0041b0830420002001280270200210022003410546044020012802101a0b20014190016a24000f0b000b2a01017f230041106b2203240020032001370308200320003703002002200341101011200341106a24000b31000240200120024b200220044b720d002002200220016b2202490d00200020023602042000200120036a3602000f0b000b2d01017f2000280208220220002802044904402000200241016a360208200028020020026a20013a00000f0b000b2601017f230041106b220224002002200036020c20012002410c6a41041011200241106a24000b550020002802002200413f4d044020012000410274102b0f0b200041ffff004d04402000410274410172200110190f0b200041ffffffff034d044020004102744102722001102c0f0b20014103102b20002001102c0b27002000280200200041086a280200200110242000410c6a280200200041146a280200200110240b0bc102040041a080040b8a0150696e6b4c6f6767657201010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010041ec81040b330202020202020202020202020202020202020202020202020202020202020303030303030303030303030303030304040404040041aa82040b0b7379733a3a70656c6c65740041ca82040b5b7068616c612e70696e6b2e6576656e74436f6e74726163744465706f73697401020304050607080a010b09000000000000000100000002000000030000000400000005000000060000000700000008000000090000000c0000000b"},"contract":{"name":"pink-system","version":"0.1.0","authors":["[your_name] <[your_email]>"]},"V3":{"spec":{"constructors":[{"args":[],"docs":[],"label":"default","payable":false,"selector":"0xed4b9d1b"}],"docs":[],"events":[],"messages":[{"args":[],"docs":[],"label":"System::version","mutates":false,"payable":false,"returnType":{"displayName":[],"type":8},"selector":"0x87c98a8d"},{"args":[{"label":"contract_id","type":{"displayName":["AccountId"],"type":0}}],"docs":[],"label":"System::grant_admin","mutates":true,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0x67612061"},{"args":[{"label":"name","type":{"displayName":["String"],"type":7}},{"label":"contract_id","type":{"displayName":["AccountId"],"type":0}}],"docs":[],"label":"System::set_driver","mutates":true,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0xaa1e2030"},{"args":[{"label":"name","type":{"displayName":["String"],"type":7}}],"docs":[],"label":"System::get_driver","mutates":false,"payable":false,"returnType":{"displayName":["Option"],"type":12},"selector":"0x2740cf0a"},{"args":[{"label":"contract_id","type":{"displayName":["AccountId"],"type":0}},{"label":"code_hash","type":{"displayName":["pink","Hash"],"type":1}}],"docs":[],"label":"System::deploy_sidevm_to","mutates":false,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0x662f4aa4"},{"args":[{"label":"contract_id","type":{"displayName":["AccountId"],"type":0}}],"docs":[],"label":"System::stop_sidevm_at","mutates":false,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0x52a0fd6a"},{"args":[{"label":"hook","type":{"displayName":["HookPoint"],"type":13}},{"label":"contract","type":{"displayName":["AccountId"],"type":0}},{"label":"selector","type":{"displayName":["u32"],"type":14}}],"docs":[],"label":"System::set_hook","mutates":true,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0x352c6b5c"},{"args":[{"label":"contract_id","type":{"displayName":["AccountId"],"type":0}},{"label":"weight","type":{"displayName":["u32"],"type":14}}],"docs":[],"label":"System::set_contract_weight","mutates":false,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0x45ec9b18"},{"args":[{"label":"contract_id","type":{"displayName":["AccountId"],"type":0}},{"label":"deposit","type":{"displayName":["Balance"],"type":15}}],"docs":[],"label":"ContractDeposit::change_deposit","mutates":true,"payable":false,"returnType":{"displayName":["Result"],"type":10},"selector":"0xa24bcb44"}]},"storage":{"struct":{"fields":[{"layout":{"cell":{"key":"0x0000000000000000000000000000000000000000000000000000000000000000","ty":0}},"name":"owner"},{"layout":{"cell":{"key":"0x0100000000000000000000000000000000000000000000000000000000000000","ty":3}},"name":"administrators"},{"layout":{"cell":{"key":"0x0200000000000000000000000000000000000000000000000000000000000000","ty":6}},"name":"drivers"}]}},"types":[{"id":0,"type":{"def":{"composite":{"fields":[{"type":1,"typeName":"[u8; 32]"}]}},"path":["ink_env","types","AccountId"]}},{"id":1,"type":{"def":{"array":{"len":32,"type":2}}}},{"id":2,"type":{"def":{"primitive":"u8"}}},{"id":3,"type":{"def":{"composite":{"fields":[{"name":"offset_key","type":5,"typeName":"Key"}]}},"params":[{"name":"K","type":0},{"name":"V","type":4}],"path":["ink_storage","lazy","mapping","Mapping"]}},{"id":4,"type":{"def":{"tuple":[]}}},{"id":5,"type":{"def":{"composite":{"fields":[{"type":1,"typeName":"[u8; 32]"}]}},"path":["ink_primitives","Key"]}},{"id":6,"type":{"def":{"composite":{"fields":[{"name":"offset_key","type":5,"typeName":"Key"}]}},"params":[{"name":"K","type":7},{"name":"V","type":0}],"path":["ink_storage","lazy","mapping","Mapping"]}},{"id":7,"type":{"def":{"primitive":"str"}}},{"id":8,"type":{"def":{"tuple":[9,9]}}},{"id":9,"type":{"def":{"primitive":"u16"}}},{"id":10,"type":{"def":{"variant":{"variants":[{"fields":[{"type":4}],"index":0,"name":"Ok"},{"fields":[{"type":11}],"index":1,"name":"Err"}]}},"params":[{"name":"T","type":4},{"name":"E","type":11}],"path":["Result"]}},{"id":11,"type":{"def":{"variant":{"variants":[{"index":0,"name":"BadOrigin"},{"index":1,"name":"DriverNotFound"}]}},"path":["pink_extension","system","Error"]}},{"id":12,"type":{"def":{"variant":{"variants":[{"index":0,"name":"None"},{"fields":[{"type":0}],"index":1,"name":"Some"}]}},"params":[{"name":"T","type":0}],"path":["Option"]}},{"id":13,"type":{"def":{"variant":{"variants":[{"index":0,"name":"OnBlockEnd"}]}},"path":["pink_extension","HookPoint"]}},{"id":14,"type":{"def":{"primitive":"u32"}}},{"id":15,"type":{"def":{"primitive":"u128"}}}]}} \ No newline at end of file diff --git a/e2e/src/fullstack.js b/e2e/src/fullstack.js index 8c8db969d9..a95c58bf6d 100644 --- a/e2e/src/fullstack.js +++ b/e2e/src/fullstack.js @@ -641,7 +641,7 @@ describe('A full stack', function () { assert.isFalse(await checkUntil(async () => { const { output } = await ContractSystemChecker.query.onBlockEndCalled(certAlice, {}); return output.valueOf(); - }, 6000*2), 'Set hook should not success without granting admin first'); + }, 6000 * 2), 'Set hook should not success without granting admin first'); }); it('can set hook with admin permission', async function () { @@ -656,7 +656,24 @@ describe('A full stack', function () { assert.isTrue(await checkUntil(async () => { const { output } = await ContractSystemChecker.query.onBlockEndCalled(certAlice, {}); return output.valueOf(); - }, 6000*2), 'Set hook should success after granted admin'); + }, 2 * 6000), 'Set hook should success after granted admin'); + }); + + it('tokenomic driver works', async function () { + await assert.txAccepted( + ContractSystem.tx['system::setDriver']({}, "ContractDeposit", ContractSystemChecker.address), + alice, + ); + const CENTS = 10_000_000_000; + const weight = 10; + await assert.txAccepted( + api.tx.phalaFatTokenomic.adjustStake(ContractSystemChecker.address, weight * CENTS), + alice, + ); + assert.isTrue(await checkUntil(async () => { + const info = await pruntime[0].getContractInfo(ContractSystemChecker.address.toHex()); + return info?.weight == weight; + }, 4 * 6000), 'Failed to apply deposit to contract weight'); }); it('cannot dup-instantiate', async function () { diff --git a/e2e/src/proto/pruntime_rpc.d.ts b/e2e/src/proto/pruntime_rpc.d.ts index 5f3d51b1b1..b42617848e 100644 --- a/e2e/src/proto/pruntime_rpc.d.ts +++ b/e2e/src/proto/pruntime_rpc.d.ts @@ -329,6 +329,34 @@ export namespace pruntime_rpc { * @returns Promise */ public httpFetch(request: pruntime_rpc.IHttpRequest): Promise; + + /** + * Calls GetContractInfo. + * @param request GetContractInfoRequest message or plain object + * @param callback Node-style callback called with the error, if any, and GetContractInfoResponse + */ + public getContractInfo(request: pruntime_rpc.IGetContractInfoRequest, callback: pruntime_rpc.PhactoryAPI.GetContractInfoCallback): void; + + /** + * Calls GetContractInfo. + * @param request GetContractInfoRequest message or plain object + * @returns Promise + */ + public getContractInfo(request: pruntime_rpc.IGetContractInfoRequest): Promise; + + /** + * Calls GetClusterInfo. + * @param request Empty message or plain object + * @param callback Node-style callback called with the error, if any, and GetClusterInfoResponse + */ + public getClusterInfo(request: google.protobuf.IEmpty, callback: pruntime_rpc.PhactoryAPI.GetClusterInfoCallback): void; + + /** + * Calls GetClusterInfo. + * @param request Empty message or plain object + * @returns Promise + */ + public getClusterInfo(request: google.protobuf.IEmpty): Promise; } namespace PhactoryAPI { @@ -486,6 +514,20 @@ export namespace pruntime_rpc { * @param [response] HttpResponse */ type HttpFetchCallback = (error: (Error|null), response?: pruntime_rpc.HttpResponse) => void; + + /** + * Callback as used by {@link pruntime_rpc.PhactoryAPI#getContractInfo}. + * @param error Error, if any + * @param [response] GetContractInfoResponse + */ + type GetContractInfoCallback = (error: (Error|null), response?: pruntime_rpc.GetContractInfoResponse) => void; + + /** + * Callback as used by {@link pruntime_rpc.PhactoryAPI#getClusterInfo}. + * @param error Error, if any + * @param [response] GetClusterInfoResponse + */ + type GetClusterInfoCallback = (error: (Error|null), response?: pruntime_rpc.GetClusterInfoResponse) => void; } /** Properties of a PhactoryInfo. */ @@ -4732,6 +4774,600 @@ export namespace pruntime_rpc { */ public toJSON(): { [k: string]: any }; } + + /** Properties of a GetContractInfoRequest. */ + interface IGetContractInfoRequest { + + /** GetContractInfoRequest contractIds */ + contractIds?: (string[]|null); + } + + /** Represents a GetContractInfoRequest. */ + class GetContractInfoRequest implements IGetContractInfoRequest { + + /** + * Constructs a new GetContractInfoRequest. + * @param [properties] Properties to set + */ + constructor(properties?: pruntime_rpc.IGetContractInfoRequest); + + /** GetContractInfoRequest contractIds. */ + public contractIds: string[]; + + /** + * Creates a new GetContractInfoRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns GetContractInfoRequest instance + */ + public static create(properties?: pruntime_rpc.IGetContractInfoRequest): pruntime_rpc.GetContractInfoRequest; + + /** + * Encodes the specified GetContractInfoRequest message. Does not implicitly {@link pruntime_rpc.GetContractInfoRequest.verify|verify} messages. + * @param message GetContractInfoRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: pruntime_rpc.IGetContractInfoRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified GetContractInfoRequest message, length delimited. Does not implicitly {@link pruntime_rpc.GetContractInfoRequest.verify|verify} messages. + * @param message GetContractInfoRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: pruntime_rpc.IGetContractInfoRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a GetContractInfoRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns GetContractInfoRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): pruntime_rpc.GetContractInfoRequest; + + /** + * Decodes a GetContractInfoRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns GetContractInfoRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): pruntime_rpc.GetContractInfoRequest; + + /** + * Verifies a GetContractInfoRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a GetContractInfoRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns GetContractInfoRequest + */ + public static fromObject(object: { [k: string]: any }): pruntime_rpc.GetContractInfoRequest; + + /** + * Creates a plain object from a GetContractInfoRequest message. Also converts values to other types if specified. + * @param message GetContractInfoRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: pruntime_rpc.GetContractInfoRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this GetContractInfoRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a GetContractInfoResponse. */ + interface IGetContractInfoResponse { + + /** GetContractInfoResponse contracts */ + contracts?: (pruntime_rpc.IContractInfo[]|null); + } + + /** Represents a GetContractInfoResponse. */ + class GetContractInfoResponse implements IGetContractInfoResponse { + + /** + * Constructs a new GetContractInfoResponse. + * @param [properties] Properties to set + */ + constructor(properties?: pruntime_rpc.IGetContractInfoResponse); + + /** GetContractInfoResponse contracts. */ + public contracts: pruntime_rpc.IContractInfo[]; + + /** + * Creates a new GetContractInfoResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns GetContractInfoResponse instance + */ + public static create(properties?: pruntime_rpc.IGetContractInfoResponse): pruntime_rpc.GetContractInfoResponse; + + /** + * Encodes the specified GetContractInfoResponse message. Does not implicitly {@link pruntime_rpc.GetContractInfoResponse.verify|verify} messages. + * @param message GetContractInfoResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: pruntime_rpc.IGetContractInfoResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified GetContractInfoResponse message, length delimited. Does not implicitly {@link pruntime_rpc.GetContractInfoResponse.verify|verify} messages. + * @param message GetContractInfoResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: pruntime_rpc.IGetContractInfoResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a GetContractInfoResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns GetContractInfoResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): pruntime_rpc.GetContractInfoResponse; + + /** + * Decodes a GetContractInfoResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns GetContractInfoResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): pruntime_rpc.GetContractInfoResponse; + + /** + * Verifies a GetContractInfoResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a GetContractInfoResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns GetContractInfoResponse + */ + public static fromObject(object: { [k: string]: any }): pruntime_rpc.GetContractInfoResponse; + + /** + * Creates a plain object from a GetContractInfoResponse message. Also converts values to other types if specified. + * @param message GetContractInfoResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: pruntime_rpc.GetContractInfoResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this GetContractInfoResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ContractInfo. */ + interface IContractInfo { + + /** ContractInfo id */ + id?: (string|null); + + /** ContractInfo codeHash */ + codeHash?: (string|null); + + /** ContractInfo weight */ + weight?: (number|null); + + /** ContractInfo sidevm */ + sidevm?: (pruntime_rpc.ISidevmInfo|null); + } + + /** Represents a ContractInfo. */ + class ContractInfo implements IContractInfo { + + /** + * Constructs a new ContractInfo. + * @param [properties] Properties to set + */ + constructor(properties?: pruntime_rpc.IContractInfo); + + /** ContractInfo id. */ + public id: string; + + /** ContractInfo codeHash. */ + public codeHash: string; + + /** ContractInfo weight. */ + public weight: number; + + /** ContractInfo sidevm. */ + public sidevm?: (pruntime_rpc.ISidevmInfo|null); + + /** + * Creates a new ContractInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns ContractInfo instance + */ + public static create(properties?: pruntime_rpc.IContractInfo): pruntime_rpc.ContractInfo; + + /** + * Encodes the specified ContractInfo message. Does not implicitly {@link pruntime_rpc.ContractInfo.verify|verify} messages. + * @param message ContractInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: pruntime_rpc.IContractInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ContractInfo message, length delimited. Does not implicitly {@link pruntime_rpc.ContractInfo.verify|verify} messages. + * @param message ContractInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: pruntime_rpc.IContractInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ContractInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ContractInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): pruntime_rpc.ContractInfo; + + /** + * Decodes a ContractInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ContractInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): pruntime_rpc.ContractInfo; + + /** + * Verifies a ContractInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ContractInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ContractInfo + */ + public static fromObject(object: { [k: string]: any }): pruntime_rpc.ContractInfo; + + /** + * Creates a plain object from a ContractInfo message. Also converts values to other types if specified. + * @param message ContractInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: pruntime_rpc.ContractInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ContractInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SidevmInfo. */ + interface ISidevmInfo { + + /** SidevmInfo state */ + state?: (string|null); + + /** SidevmInfo codeHash */ + codeHash?: (string|null); + + /** SidevmInfo startTime */ + startTime?: (string|null); + + /** SidevmInfo stopReason */ + stopReason?: (string|null); + } + + /** Represents a SidevmInfo. */ + class SidevmInfo implements ISidevmInfo { + + /** + * Constructs a new SidevmInfo. + * @param [properties] Properties to set + */ + constructor(properties?: pruntime_rpc.ISidevmInfo); + + /** SidevmInfo state. */ + public state: string; + + /** SidevmInfo codeHash. */ + public codeHash: string; + + /** SidevmInfo startTime. */ + public startTime: string; + + /** SidevmInfo stopReason. */ + public stopReason: string; + + /** + * Creates a new SidevmInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns SidevmInfo instance + */ + public static create(properties?: pruntime_rpc.ISidevmInfo): pruntime_rpc.SidevmInfo; + + /** + * Encodes the specified SidevmInfo message. Does not implicitly {@link pruntime_rpc.SidevmInfo.verify|verify} messages. + * @param message SidevmInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: pruntime_rpc.ISidevmInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SidevmInfo message, length delimited. Does not implicitly {@link pruntime_rpc.SidevmInfo.verify|verify} messages. + * @param message SidevmInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: pruntime_rpc.ISidevmInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SidevmInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SidevmInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): pruntime_rpc.SidevmInfo; + + /** + * Decodes a SidevmInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SidevmInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): pruntime_rpc.SidevmInfo; + + /** + * Verifies a SidevmInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SidevmInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SidevmInfo + */ + public static fromObject(object: { [k: string]: any }): pruntime_rpc.SidevmInfo; + + /** + * Creates a plain object from a SidevmInfo message. Also converts values to other types if specified. + * @param message SidevmInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: pruntime_rpc.SidevmInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SidevmInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a GetClusterInfoResponse. */ + interface IGetClusterInfoResponse { + + /** GetClusterInfoResponse clusters */ + clusters?: (pruntime_rpc.IClusterInfo[]|null); + } + + /** Represents a GetClusterInfoResponse. */ + class GetClusterInfoResponse implements IGetClusterInfoResponse { + + /** + * Constructs a new GetClusterInfoResponse. + * @param [properties] Properties to set + */ + constructor(properties?: pruntime_rpc.IGetClusterInfoResponse); + + /** GetClusterInfoResponse clusters. */ + public clusters: pruntime_rpc.IClusterInfo[]; + + /** + * Creates a new GetClusterInfoResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns GetClusterInfoResponse instance + */ + public static create(properties?: pruntime_rpc.IGetClusterInfoResponse): pruntime_rpc.GetClusterInfoResponse; + + /** + * Encodes the specified GetClusterInfoResponse message. Does not implicitly {@link pruntime_rpc.GetClusterInfoResponse.verify|verify} messages. + * @param message GetClusterInfoResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: pruntime_rpc.IGetClusterInfoResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified GetClusterInfoResponse message, length delimited. Does not implicitly {@link pruntime_rpc.GetClusterInfoResponse.verify|verify} messages. + * @param message GetClusterInfoResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: pruntime_rpc.IGetClusterInfoResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a GetClusterInfoResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns GetClusterInfoResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): pruntime_rpc.GetClusterInfoResponse; + + /** + * Decodes a GetClusterInfoResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns GetClusterInfoResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): pruntime_rpc.GetClusterInfoResponse; + + /** + * Verifies a GetClusterInfoResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a GetClusterInfoResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns GetClusterInfoResponse + */ + public static fromObject(object: { [k: string]: any }): pruntime_rpc.GetClusterInfoResponse; + + /** + * Creates a plain object from a GetClusterInfoResponse message. Also converts values to other types if specified. + * @param message GetClusterInfoResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: pruntime_rpc.GetClusterInfoResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this GetClusterInfoResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ClusterInfo. */ + interface IClusterInfo { + + /** ClusterInfo id */ + id?: (string|null); + + /** ClusterInfo version */ + version?: (string|null); + + /** ClusterInfo stateRoot */ + stateRoot?: (string|null); + + /** ClusterInfo contracts */ + contracts?: (string[]|null); + } + + /** Represents a ClusterInfo. */ + class ClusterInfo implements IClusterInfo { + + /** + * Constructs a new ClusterInfo. + * @param [properties] Properties to set + */ + constructor(properties?: pruntime_rpc.IClusterInfo); + + /** ClusterInfo id. */ + public id: string; + + /** ClusterInfo version. */ + public version: string; + + /** ClusterInfo stateRoot. */ + public stateRoot: string; + + /** ClusterInfo contracts. */ + public contracts: string[]; + + /** + * Creates a new ClusterInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns ClusterInfo instance + */ + public static create(properties?: pruntime_rpc.IClusterInfo): pruntime_rpc.ClusterInfo; + + /** + * Encodes the specified ClusterInfo message. Does not implicitly {@link pruntime_rpc.ClusterInfo.verify|verify} messages. + * @param message ClusterInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: pruntime_rpc.IClusterInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ClusterInfo message, length delimited. Does not implicitly {@link pruntime_rpc.ClusterInfo.verify|verify} messages. + * @param message ClusterInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: pruntime_rpc.IClusterInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ClusterInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ClusterInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): pruntime_rpc.ClusterInfo; + + /** + * Decodes a ClusterInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ClusterInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): pruntime_rpc.ClusterInfo; + + /** + * Verifies a ClusterInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ClusterInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ClusterInfo + */ + public static fromObject(object: { [k: string]: any }): pruntime_rpc.ClusterInfo; + + /** + * Creates a plain object from a ClusterInfo message. Also converts values to other types if specified. + * @param message ClusterInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: pruntime_rpc.ClusterInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ClusterInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } } /** Namespace google. */ diff --git a/e2e/src/proto/pruntime_rpc.js b/e2e/src/proto/pruntime_rpc.js index 743f9c8c97..79cd9eadc2 100644 --- a/e2e/src/proto/pruntime_rpc.js +++ b/e2e/src/proto/pruntime_rpc.js @@ -776,6 +776,72 @@ $root.pruntime_rpc = (function() { * @variation 2 */ + /** + * Callback as used by {@link pruntime_rpc.PhactoryAPI#getContractInfo}. + * @memberof pruntime_rpc.PhactoryAPI + * @typedef GetContractInfoCallback + * @type {function} + * @param {Error|null} error Error, if any + * @param {pruntime_rpc.GetContractInfoResponse} [response] GetContractInfoResponse + */ + + /** + * Calls GetContractInfo. + * @function getContractInfo + * @memberof pruntime_rpc.PhactoryAPI + * @instance + * @param {pruntime_rpc.IGetContractInfoRequest} request GetContractInfoRequest message or plain object + * @param {pruntime_rpc.PhactoryAPI.GetContractInfoCallback} callback Node-style callback called with the error, if any, and GetContractInfoResponse + * @returns {undefined} + * @variation 1 + */ + Object.defineProperty(PhactoryAPI.prototype.getContractInfo = function getContractInfo(request, callback) { + return this.rpcCall(getContractInfo, $root.pruntime_rpc.GetContractInfoRequest, $root.pruntime_rpc.GetContractInfoResponse, request, callback); + }, "name", { value: "GetContractInfo" }); + + /** + * Calls GetContractInfo. + * @function getContractInfo + * @memberof pruntime_rpc.PhactoryAPI + * @instance + * @param {pruntime_rpc.IGetContractInfoRequest} request GetContractInfoRequest message or plain object + * @returns {Promise} Promise + * @variation 2 + */ + + /** + * Callback as used by {@link pruntime_rpc.PhactoryAPI#getClusterInfo}. + * @memberof pruntime_rpc.PhactoryAPI + * @typedef GetClusterInfoCallback + * @type {function} + * @param {Error|null} error Error, if any + * @param {pruntime_rpc.GetClusterInfoResponse} [response] GetClusterInfoResponse + */ + + /** + * Calls GetClusterInfo. + * @function getClusterInfo + * @memberof pruntime_rpc.PhactoryAPI + * @instance + * @param {google.protobuf.IEmpty} request Empty message or plain object + * @param {pruntime_rpc.PhactoryAPI.GetClusterInfoCallback} callback Node-style callback called with the error, if any, and GetClusterInfoResponse + * @returns {undefined} + * @variation 1 + */ + Object.defineProperty(PhactoryAPI.prototype.getClusterInfo = function getClusterInfo(request, callback) { + return this.rpcCall(getClusterInfo, $root.google.protobuf.Empty, $root.pruntime_rpc.GetClusterInfoResponse, request, callback); + }, "name", { value: "GetClusterInfo" }); + + /** + * Calls GetClusterInfo. + * @function getClusterInfo + * @memberof pruntime_rpc.PhactoryAPI + * @instance + * @param {google.protobuf.IEmpty} request Empty message or plain object + * @returns {Promise} Promise + * @variation 2 + */ + return PhactoryAPI; })(); @@ -11437,6 +11503,1409 @@ $root.pruntime_rpc = (function() { return HttpResponse; })(); + pruntime_rpc.GetContractInfoRequest = (function() { + + /** + * Properties of a GetContractInfoRequest. + * @memberof pruntime_rpc + * @interface IGetContractInfoRequest + * @property {Array.|null} [contractIds] GetContractInfoRequest contractIds + */ + + /** + * Constructs a new GetContractInfoRequest. + * @memberof pruntime_rpc + * @classdesc Represents a GetContractInfoRequest. + * @implements IGetContractInfoRequest + * @constructor + * @param {pruntime_rpc.IGetContractInfoRequest=} [properties] Properties to set + */ + function GetContractInfoRequest(properties) { + this.contractIds = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * GetContractInfoRequest contractIds. + * @member {Array.} contractIds + * @memberof pruntime_rpc.GetContractInfoRequest + * @instance + */ + GetContractInfoRequest.prototype.contractIds = $util.emptyArray; + + /** + * Creates a new GetContractInfoRequest instance using the specified properties. + * @function create + * @memberof pruntime_rpc.GetContractInfoRequest + * @static + * @param {pruntime_rpc.IGetContractInfoRequest=} [properties] Properties to set + * @returns {pruntime_rpc.GetContractInfoRequest} GetContractInfoRequest instance + */ + GetContractInfoRequest.create = function create(properties) { + return new GetContractInfoRequest(properties); + }; + + /** + * Encodes the specified GetContractInfoRequest message. Does not implicitly {@link pruntime_rpc.GetContractInfoRequest.verify|verify} messages. + * @function encode + * @memberof pruntime_rpc.GetContractInfoRequest + * @static + * @param {pruntime_rpc.IGetContractInfoRequest} message GetContractInfoRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GetContractInfoRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.contractIds != null && message.contractIds.length) + for (var i = 0; i < message.contractIds.length; ++i) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.contractIds[i]); + return writer; + }; + + /** + * Encodes the specified GetContractInfoRequest message, length delimited. Does not implicitly {@link pruntime_rpc.GetContractInfoRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof pruntime_rpc.GetContractInfoRequest + * @static + * @param {pruntime_rpc.IGetContractInfoRequest} message GetContractInfoRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GetContractInfoRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a GetContractInfoRequest message from the specified reader or buffer. + * @function decode + * @memberof pruntime_rpc.GetContractInfoRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {pruntime_rpc.GetContractInfoRequest} GetContractInfoRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GetContractInfoRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.pruntime_rpc.GetContractInfoRequest(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.contractIds && message.contractIds.length)) + message.contractIds = []; + message.contractIds.push(reader.string()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a GetContractInfoRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof pruntime_rpc.GetContractInfoRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {pruntime_rpc.GetContractInfoRequest} GetContractInfoRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GetContractInfoRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a GetContractInfoRequest message. + * @function verify + * @memberof pruntime_rpc.GetContractInfoRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + GetContractInfoRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.contractIds != null && message.hasOwnProperty("contractIds")) { + if (!Array.isArray(message.contractIds)) + return "contractIds: array expected"; + for (var i = 0; i < message.contractIds.length; ++i) + if (!$util.isString(message.contractIds[i])) + return "contractIds: string[] expected"; + } + return null; + }; + + /** + * Creates a GetContractInfoRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof pruntime_rpc.GetContractInfoRequest + * @static + * @param {Object.} object Plain object + * @returns {pruntime_rpc.GetContractInfoRequest} GetContractInfoRequest + */ + GetContractInfoRequest.fromObject = function fromObject(object) { + if (object instanceof $root.pruntime_rpc.GetContractInfoRequest) + return object; + var message = new $root.pruntime_rpc.GetContractInfoRequest(); + if (object.contractIds) { + if (!Array.isArray(object.contractIds)) + throw TypeError(".pruntime_rpc.GetContractInfoRequest.contractIds: array expected"); + message.contractIds = []; + for (var i = 0; i < object.contractIds.length; ++i) + message.contractIds[i] = String(object.contractIds[i]); + } + return message; + }; + + /** + * Creates a plain object from a GetContractInfoRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof pruntime_rpc.GetContractInfoRequest + * @static + * @param {pruntime_rpc.GetContractInfoRequest} message GetContractInfoRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + GetContractInfoRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.contractIds = []; + if (message.contractIds && message.contractIds.length) { + object.contractIds = []; + for (var j = 0; j < message.contractIds.length; ++j) + object.contractIds[j] = message.contractIds[j]; + } + return object; + }; + + /** + * Converts this GetContractInfoRequest to JSON. + * @function toJSON + * @memberof pruntime_rpc.GetContractInfoRequest + * @instance + * @returns {Object.} JSON object + */ + GetContractInfoRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return GetContractInfoRequest; + })(); + + pruntime_rpc.GetContractInfoResponse = (function() { + + /** + * Properties of a GetContractInfoResponse. + * @memberof pruntime_rpc + * @interface IGetContractInfoResponse + * @property {Array.|null} [contracts] GetContractInfoResponse contracts + */ + + /** + * Constructs a new GetContractInfoResponse. + * @memberof pruntime_rpc + * @classdesc Represents a GetContractInfoResponse. + * @implements IGetContractInfoResponse + * @constructor + * @param {pruntime_rpc.IGetContractInfoResponse=} [properties] Properties to set + */ + function GetContractInfoResponse(properties) { + this.contracts = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * GetContractInfoResponse contracts. + * @member {Array.} contracts + * @memberof pruntime_rpc.GetContractInfoResponse + * @instance + */ + GetContractInfoResponse.prototype.contracts = $util.emptyArray; + + /** + * Creates a new GetContractInfoResponse instance using the specified properties. + * @function create + * @memberof pruntime_rpc.GetContractInfoResponse + * @static + * @param {pruntime_rpc.IGetContractInfoResponse=} [properties] Properties to set + * @returns {pruntime_rpc.GetContractInfoResponse} GetContractInfoResponse instance + */ + GetContractInfoResponse.create = function create(properties) { + return new GetContractInfoResponse(properties); + }; + + /** + * Encodes the specified GetContractInfoResponse message. Does not implicitly {@link pruntime_rpc.GetContractInfoResponse.verify|verify} messages. + * @function encode + * @memberof pruntime_rpc.GetContractInfoResponse + * @static + * @param {pruntime_rpc.IGetContractInfoResponse} message GetContractInfoResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GetContractInfoResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.contracts != null && message.contracts.length) + for (var i = 0; i < message.contracts.length; ++i) + $root.pruntime_rpc.ContractInfo.encode(message.contracts[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified GetContractInfoResponse message, length delimited. Does not implicitly {@link pruntime_rpc.GetContractInfoResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof pruntime_rpc.GetContractInfoResponse + * @static + * @param {pruntime_rpc.IGetContractInfoResponse} message GetContractInfoResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GetContractInfoResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a GetContractInfoResponse message from the specified reader or buffer. + * @function decode + * @memberof pruntime_rpc.GetContractInfoResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {pruntime_rpc.GetContractInfoResponse} GetContractInfoResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GetContractInfoResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.pruntime_rpc.GetContractInfoResponse(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.contracts && message.contracts.length)) + message.contracts = []; + message.contracts.push($root.pruntime_rpc.ContractInfo.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a GetContractInfoResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof pruntime_rpc.GetContractInfoResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {pruntime_rpc.GetContractInfoResponse} GetContractInfoResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GetContractInfoResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a GetContractInfoResponse message. + * @function verify + * @memberof pruntime_rpc.GetContractInfoResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + GetContractInfoResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.contracts != null && message.hasOwnProperty("contracts")) { + if (!Array.isArray(message.contracts)) + return "contracts: array expected"; + for (var i = 0; i < message.contracts.length; ++i) { + var error = $root.pruntime_rpc.ContractInfo.verify(message.contracts[i]); + if (error) + return "contracts." + error; + } + } + return null; + }; + + /** + * Creates a GetContractInfoResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof pruntime_rpc.GetContractInfoResponse + * @static + * @param {Object.} object Plain object + * @returns {pruntime_rpc.GetContractInfoResponse} GetContractInfoResponse + */ + GetContractInfoResponse.fromObject = function fromObject(object) { + if (object instanceof $root.pruntime_rpc.GetContractInfoResponse) + return object; + var message = new $root.pruntime_rpc.GetContractInfoResponse(); + if (object.contracts) { + if (!Array.isArray(object.contracts)) + throw TypeError(".pruntime_rpc.GetContractInfoResponse.contracts: array expected"); + message.contracts = []; + for (var i = 0; i < object.contracts.length; ++i) { + if (typeof object.contracts[i] !== "object") + throw TypeError(".pruntime_rpc.GetContractInfoResponse.contracts: object expected"); + message.contracts[i] = $root.pruntime_rpc.ContractInfo.fromObject(object.contracts[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a GetContractInfoResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof pruntime_rpc.GetContractInfoResponse + * @static + * @param {pruntime_rpc.GetContractInfoResponse} message GetContractInfoResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + GetContractInfoResponse.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.contracts = []; + if (message.contracts && message.contracts.length) { + object.contracts = []; + for (var j = 0; j < message.contracts.length; ++j) + object.contracts[j] = $root.pruntime_rpc.ContractInfo.toObject(message.contracts[j], options); + } + return object; + }; + + /** + * Converts this GetContractInfoResponse to JSON. + * @function toJSON + * @memberof pruntime_rpc.GetContractInfoResponse + * @instance + * @returns {Object.} JSON object + */ + GetContractInfoResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return GetContractInfoResponse; + })(); + + pruntime_rpc.ContractInfo = (function() { + + /** + * Properties of a ContractInfo. + * @memberof pruntime_rpc + * @interface IContractInfo + * @property {string|null} [id] ContractInfo id + * @property {string|null} [codeHash] ContractInfo codeHash + * @property {number|null} [weight] ContractInfo weight + * @property {pruntime_rpc.ISidevmInfo|null} [sidevm] ContractInfo sidevm + */ + + /** + * Constructs a new ContractInfo. + * @memberof pruntime_rpc + * @classdesc Represents a ContractInfo. + * @implements IContractInfo + * @constructor + * @param {pruntime_rpc.IContractInfo=} [properties] Properties to set + */ + function ContractInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ContractInfo id. + * @member {string} id + * @memberof pruntime_rpc.ContractInfo + * @instance + */ + ContractInfo.prototype.id = ""; + + /** + * ContractInfo codeHash. + * @member {string} codeHash + * @memberof pruntime_rpc.ContractInfo + * @instance + */ + ContractInfo.prototype.codeHash = ""; + + /** + * ContractInfo weight. + * @member {number} weight + * @memberof pruntime_rpc.ContractInfo + * @instance + */ + ContractInfo.prototype.weight = 0; + + /** + * ContractInfo sidevm. + * @member {pruntime_rpc.ISidevmInfo|null|undefined} sidevm + * @memberof pruntime_rpc.ContractInfo + * @instance + */ + ContractInfo.prototype.sidevm = null; + + /** + * Creates a new ContractInfo instance using the specified properties. + * @function create + * @memberof pruntime_rpc.ContractInfo + * @static + * @param {pruntime_rpc.IContractInfo=} [properties] Properties to set + * @returns {pruntime_rpc.ContractInfo} ContractInfo instance + */ + ContractInfo.create = function create(properties) { + return new ContractInfo(properties); + }; + + /** + * Encodes the specified ContractInfo message. Does not implicitly {@link pruntime_rpc.ContractInfo.verify|verify} messages. + * @function encode + * @memberof pruntime_rpc.ContractInfo + * @static + * @param {pruntime_rpc.IContractInfo} message ContractInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ContractInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.codeHash != null && Object.hasOwnProperty.call(message, "codeHash")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.codeHash); + if (message.weight != null && Object.hasOwnProperty.call(message, "weight")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.weight); + if (message.sidevm != null && Object.hasOwnProperty.call(message, "sidevm")) + $root.pruntime_rpc.SidevmInfo.encode(message.sidevm, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified ContractInfo message, length delimited. Does not implicitly {@link pruntime_rpc.ContractInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof pruntime_rpc.ContractInfo + * @static + * @param {pruntime_rpc.IContractInfo} message ContractInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ContractInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ContractInfo message from the specified reader or buffer. + * @function decode + * @memberof pruntime_rpc.ContractInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {pruntime_rpc.ContractInfo} ContractInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ContractInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.pruntime_rpc.ContractInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.codeHash = reader.string(); + break; + case 3: + message.weight = reader.uint32(); + break; + case 4: + message.sidevm = $root.pruntime_rpc.SidevmInfo.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ContractInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof pruntime_rpc.ContractInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {pruntime_rpc.ContractInfo} ContractInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ContractInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ContractInfo message. + * @function verify + * @memberof pruntime_rpc.ContractInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ContractInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.codeHash != null && message.hasOwnProperty("codeHash")) + if (!$util.isString(message.codeHash)) + return "codeHash: string expected"; + if (message.weight != null && message.hasOwnProperty("weight")) + if (!$util.isInteger(message.weight)) + return "weight: integer expected"; + if (message.sidevm != null && message.hasOwnProperty("sidevm")) { + var error = $root.pruntime_rpc.SidevmInfo.verify(message.sidevm); + if (error) + return "sidevm." + error; + } + return null; + }; + + /** + * Creates a ContractInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof pruntime_rpc.ContractInfo + * @static + * @param {Object.} object Plain object + * @returns {pruntime_rpc.ContractInfo} ContractInfo + */ + ContractInfo.fromObject = function fromObject(object) { + if (object instanceof $root.pruntime_rpc.ContractInfo) + return object; + var message = new $root.pruntime_rpc.ContractInfo(); + if (object.id != null) + message.id = String(object.id); + if (object.codeHash != null) + message.codeHash = String(object.codeHash); + if (object.weight != null) + message.weight = object.weight >>> 0; + if (object.sidevm != null) { + if (typeof object.sidevm !== "object") + throw TypeError(".pruntime_rpc.ContractInfo.sidevm: object expected"); + message.sidevm = $root.pruntime_rpc.SidevmInfo.fromObject(object.sidevm); + } + return message; + }; + + /** + * Creates a plain object from a ContractInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof pruntime_rpc.ContractInfo + * @static + * @param {pruntime_rpc.ContractInfo} message ContractInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ContractInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.id = ""; + object.codeHash = ""; + object.weight = 0; + object.sidevm = null; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.codeHash != null && message.hasOwnProperty("codeHash")) + object.codeHash = message.codeHash; + if (message.weight != null && message.hasOwnProperty("weight")) + object.weight = message.weight; + if (message.sidevm != null && message.hasOwnProperty("sidevm")) + object.sidevm = $root.pruntime_rpc.SidevmInfo.toObject(message.sidevm, options); + return object; + }; + + /** + * Converts this ContractInfo to JSON. + * @function toJSON + * @memberof pruntime_rpc.ContractInfo + * @instance + * @returns {Object.} JSON object + */ + ContractInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ContractInfo; + })(); + + pruntime_rpc.SidevmInfo = (function() { + + /** + * Properties of a SidevmInfo. + * @memberof pruntime_rpc + * @interface ISidevmInfo + * @property {string|null} [state] SidevmInfo state + * @property {string|null} [codeHash] SidevmInfo codeHash + * @property {string|null} [startTime] SidevmInfo startTime + * @property {string|null} [stopReason] SidevmInfo stopReason + */ + + /** + * Constructs a new SidevmInfo. + * @memberof pruntime_rpc + * @classdesc Represents a SidevmInfo. + * @implements ISidevmInfo + * @constructor + * @param {pruntime_rpc.ISidevmInfo=} [properties] Properties to set + */ + function SidevmInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SidevmInfo state. + * @member {string} state + * @memberof pruntime_rpc.SidevmInfo + * @instance + */ + SidevmInfo.prototype.state = ""; + + /** + * SidevmInfo codeHash. + * @member {string} codeHash + * @memberof pruntime_rpc.SidevmInfo + * @instance + */ + SidevmInfo.prototype.codeHash = ""; + + /** + * SidevmInfo startTime. + * @member {string} startTime + * @memberof pruntime_rpc.SidevmInfo + * @instance + */ + SidevmInfo.prototype.startTime = ""; + + /** + * SidevmInfo stopReason. + * @member {string} stopReason + * @memberof pruntime_rpc.SidevmInfo + * @instance + */ + SidevmInfo.prototype.stopReason = ""; + + /** + * Creates a new SidevmInfo instance using the specified properties. + * @function create + * @memberof pruntime_rpc.SidevmInfo + * @static + * @param {pruntime_rpc.ISidevmInfo=} [properties] Properties to set + * @returns {pruntime_rpc.SidevmInfo} SidevmInfo instance + */ + SidevmInfo.create = function create(properties) { + return new SidevmInfo(properties); + }; + + /** + * Encodes the specified SidevmInfo message. Does not implicitly {@link pruntime_rpc.SidevmInfo.verify|verify} messages. + * @function encode + * @memberof pruntime_rpc.SidevmInfo + * @static + * @param {pruntime_rpc.ISidevmInfo} message SidevmInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SidevmInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.state != null && Object.hasOwnProperty.call(message, "state")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.state); + if (message.codeHash != null && Object.hasOwnProperty.call(message, "codeHash")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.codeHash); + if (message.startTime != null && Object.hasOwnProperty.call(message, "startTime")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.startTime); + if (message.stopReason != null && Object.hasOwnProperty.call(message, "stopReason")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.stopReason); + return writer; + }; + + /** + * Encodes the specified SidevmInfo message, length delimited. Does not implicitly {@link pruntime_rpc.SidevmInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof pruntime_rpc.SidevmInfo + * @static + * @param {pruntime_rpc.ISidevmInfo} message SidevmInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SidevmInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SidevmInfo message from the specified reader or buffer. + * @function decode + * @memberof pruntime_rpc.SidevmInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {pruntime_rpc.SidevmInfo} SidevmInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SidevmInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.pruntime_rpc.SidevmInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.state = reader.string(); + break; + case 2: + message.codeHash = reader.string(); + break; + case 3: + message.startTime = reader.string(); + break; + case 4: + message.stopReason = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SidevmInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof pruntime_rpc.SidevmInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {pruntime_rpc.SidevmInfo} SidevmInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SidevmInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SidevmInfo message. + * @function verify + * @memberof pruntime_rpc.SidevmInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SidevmInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.state != null && message.hasOwnProperty("state")) + if (!$util.isString(message.state)) + return "state: string expected"; + if (message.codeHash != null && message.hasOwnProperty("codeHash")) + if (!$util.isString(message.codeHash)) + return "codeHash: string expected"; + if (message.startTime != null && message.hasOwnProperty("startTime")) + if (!$util.isString(message.startTime)) + return "startTime: string expected"; + if (message.stopReason != null && message.hasOwnProperty("stopReason")) + if (!$util.isString(message.stopReason)) + return "stopReason: string expected"; + return null; + }; + + /** + * Creates a SidevmInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof pruntime_rpc.SidevmInfo + * @static + * @param {Object.} object Plain object + * @returns {pruntime_rpc.SidevmInfo} SidevmInfo + */ + SidevmInfo.fromObject = function fromObject(object) { + if (object instanceof $root.pruntime_rpc.SidevmInfo) + return object; + var message = new $root.pruntime_rpc.SidevmInfo(); + if (object.state != null) + message.state = String(object.state); + if (object.codeHash != null) + message.codeHash = String(object.codeHash); + if (object.startTime != null) + message.startTime = String(object.startTime); + if (object.stopReason != null) + message.stopReason = String(object.stopReason); + return message; + }; + + /** + * Creates a plain object from a SidevmInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof pruntime_rpc.SidevmInfo + * @static + * @param {pruntime_rpc.SidevmInfo} message SidevmInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SidevmInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.state = ""; + object.codeHash = ""; + object.startTime = ""; + object.stopReason = ""; + } + if (message.state != null && message.hasOwnProperty("state")) + object.state = message.state; + if (message.codeHash != null && message.hasOwnProperty("codeHash")) + object.codeHash = message.codeHash; + if (message.startTime != null && message.hasOwnProperty("startTime")) + object.startTime = message.startTime; + if (message.stopReason != null && message.hasOwnProperty("stopReason")) + object.stopReason = message.stopReason; + return object; + }; + + /** + * Converts this SidevmInfo to JSON. + * @function toJSON + * @memberof pruntime_rpc.SidevmInfo + * @instance + * @returns {Object.} JSON object + */ + SidevmInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SidevmInfo; + })(); + + pruntime_rpc.GetClusterInfoResponse = (function() { + + /** + * Properties of a GetClusterInfoResponse. + * @memberof pruntime_rpc + * @interface IGetClusterInfoResponse + * @property {Array.|null} [clusters] GetClusterInfoResponse clusters + */ + + /** + * Constructs a new GetClusterInfoResponse. + * @memberof pruntime_rpc + * @classdesc Represents a GetClusterInfoResponse. + * @implements IGetClusterInfoResponse + * @constructor + * @param {pruntime_rpc.IGetClusterInfoResponse=} [properties] Properties to set + */ + function GetClusterInfoResponse(properties) { + this.clusters = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * GetClusterInfoResponse clusters. + * @member {Array.} clusters + * @memberof pruntime_rpc.GetClusterInfoResponse + * @instance + */ + GetClusterInfoResponse.prototype.clusters = $util.emptyArray; + + /** + * Creates a new GetClusterInfoResponse instance using the specified properties. + * @function create + * @memberof pruntime_rpc.GetClusterInfoResponse + * @static + * @param {pruntime_rpc.IGetClusterInfoResponse=} [properties] Properties to set + * @returns {pruntime_rpc.GetClusterInfoResponse} GetClusterInfoResponse instance + */ + GetClusterInfoResponse.create = function create(properties) { + return new GetClusterInfoResponse(properties); + }; + + /** + * Encodes the specified GetClusterInfoResponse message. Does not implicitly {@link pruntime_rpc.GetClusterInfoResponse.verify|verify} messages. + * @function encode + * @memberof pruntime_rpc.GetClusterInfoResponse + * @static + * @param {pruntime_rpc.IGetClusterInfoResponse} message GetClusterInfoResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GetClusterInfoResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.clusters != null && message.clusters.length) + for (var i = 0; i < message.clusters.length; ++i) + $root.pruntime_rpc.ClusterInfo.encode(message.clusters[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified GetClusterInfoResponse message, length delimited. Does not implicitly {@link pruntime_rpc.GetClusterInfoResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof pruntime_rpc.GetClusterInfoResponse + * @static + * @param {pruntime_rpc.IGetClusterInfoResponse} message GetClusterInfoResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GetClusterInfoResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a GetClusterInfoResponse message from the specified reader or buffer. + * @function decode + * @memberof pruntime_rpc.GetClusterInfoResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {pruntime_rpc.GetClusterInfoResponse} GetClusterInfoResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GetClusterInfoResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.pruntime_rpc.GetClusterInfoResponse(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.clusters && message.clusters.length)) + message.clusters = []; + message.clusters.push($root.pruntime_rpc.ClusterInfo.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a GetClusterInfoResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof pruntime_rpc.GetClusterInfoResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {pruntime_rpc.GetClusterInfoResponse} GetClusterInfoResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GetClusterInfoResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a GetClusterInfoResponse message. + * @function verify + * @memberof pruntime_rpc.GetClusterInfoResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + GetClusterInfoResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.clusters != null && message.hasOwnProperty("clusters")) { + if (!Array.isArray(message.clusters)) + return "clusters: array expected"; + for (var i = 0; i < message.clusters.length; ++i) { + var error = $root.pruntime_rpc.ClusterInfo.verify(message.clusters[i]); + if (error) + return "clusters." + error; + } + } + return null; + }; + + /** + * Creates a GetClusterInfoResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof pruntime_rpc.GetClusterInfoResponse + * @static + * @param {Object.} object Plain object + * @returns {pruntime_rpc.GetClusterInfoResponse} GetClusterInfoResponse + */ + GetClusterInfoResponse.fromObject = function fromObject(object) { + if (object instanceof $root.pruntime_rpc.GetClusterInfoResponse) + return object; + var message = new $root.pruntime_rpc.GetClusterInfoResponse(); + if (object.clusters) { + if (!Array.isArray(object.clusters)) + throw TypeError(".pruntime_rpc.GetClusterInfoResponse.clusters: array expected"); + message.clusters = []; + for (var i = 0; i < object.clusters.length; ++i) { + if (typeof object.clusters[i] !== "object") + throw TypeError(".pruntime_rpc.GetClusterInfoResponse.clusters: object expected"); + message.clusters[i] = $root.pruntime_rpc.ClusterInfo.fromObject(object.clusters[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a GetClusterInfoResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof pruntime_rpc.GetClusterInfoResponse + * @static + * @param {pruntime_rpc.GetClusterInfoResponse} message GetClusterInfoResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + GetClusterInfoResponse.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.clusters = []; + if (message.clusters && message.clusters.length) { + object.clusters = []; + for (var j = 0; j < message.clusters.length; ++j) + object.clusters[j] = $root.pruntime_rpc.ClusterInfo.toObject(message.clusters[j], options); + } + return object; + }; + + /** + * Converts this GetClusterInfoResponse to JSON. + * @function toJSON + * @memberof pruntime_rpc.GetClusterInfoResponse + * @instance + * @returns {Object.} JSON object + */ + GetClusterInfoResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return GetClusterInfoResponse; + })(); + + pruntime_rpc.ClusterInfo = (function() { + + /** + * Properties of a ClusterInfo. + * @memberof pruntime_rpc + * @interface IClusterInfo + * @property {string|null} [id] ClusterInfo id + * @property {string|null} [version] ClusterInfo version + * @property {string|null} [stateRoot] ClusterInfo stateRoot + * @property {Array.|null} [contracts] ClusterInfo contracts + */ + + /** + * Constructs a new ClusterInfo. + * @memberof pruntime_rpc + * @classdesc Represents a ClusterInfo. + * @implements IClusterInfo + * @constructor + * @param {pruntime_rpc.IClusterInfo=} [properties] Properties to set + */ + function ClusterInfo(properties) { + this.contracts = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ClusterInfo id. + * @member {string} id + * @memberof pruntime_rpc.ClusterInfo + * @instance + */ + ClusterInfo.prototype.id = ""; + + /** + * ClusterInfo version. + * @member {string} version + * @memberof pruntime_rpc.ClusterInfo + * @instance + */ + ClusterInfo.prototype.version = ""; + + /** + * ClusterInfo stateRoot. + * @member {string} stateRoot + * @memberof pruntime_rpc.ClusterInfo + * @instance + */ + ClusterInfo.prototype.stateRoot = ""; + + /** + * ClusterInfo contracts. + * @member {Array.} contracts + * @memberof pruntime_rpc.ClusterInfo + * @instance + */ + ClusterInfo.prototype.contracts = $util.emptyArray; + + /** + * Creates a new ClusterInfo instance using the specified properties. + * @function create + * @memberof pruntime_rpc.ClusterInfo + * @static + * @param {pruntime_rpc.IClusterInfo=} [properties] Properties to set + * @returns {pruntime_rpc.ClusterInfo} ClusterInfo instance + */ + ClusterInfo.create = function create(properties) { + return new ClusterInfo(properties); + }; + + /** + * Encodes the specified ClusterInfo message. Does not implicitly {@link pruntime_rpc.ClusterInfo.verify|verify} messages. + * @function encode + * @memberof pruntime_rpc.ClusterInfo + * @static + * @param {pruntime_rpc.IClusterInfo} message ClusterInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClusterInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.version); + if (message.stateRoot != null && Object.hasOwnProperty.call(message, "stateRoot")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.stateRoot); + if (message.contracts != null && message.contracts.length) + for (var i = 0; i < message.contracts.length; ++i) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.contracts[i]); + return writer; + }; + + /** + * Encodes the specified ClusterInfo message, length delimited. Does not implicitly {@link pruntime_rpc.ClusterInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof pruntime_rpc.ClusterInfo + * @static + * @param {pruntime_rpc.IClusterInfo} message ClusterInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClusterInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ClusterInfo message from the specified reader or buffer. + * @function decode + * @memberof pruntime_rpc.ClusterInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {pruntime_rpc.ClusterInfo} ClusterInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClusterInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.pruntime_rpc.ClusterInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.version = reader.string(); + break; + case 3: + message.stateRoot = reader.string(); + break; + case 4: + if (!(message.contracts && message.contracts.length)) + message.contracts = []; + message.contracts.push(reader.string()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ClusterInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof pruntime_rpc.ClusterInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {pruntime_rpc.ClusterInfo} ClusterInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClusterInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ClusterInfo message. + * @function verify + * @memberof pruntime_rpc.ClusterInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ClusterInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.version != null && message.hasOwnProperty("version")) + if (!$util.isString(message.version)) + return "version: string expected"; + if (message.stateRoot != null && message.hasOwnProperty("stateRoot")) + if (!$util.isString(message.stateRoot)) + return "stateRoot: string expected"; + if (message.contracts != null && message.hasOwnProperty("contracts")) { + if (!Array.isArray(message.contracts)) + return "contracts: array expected"; + for (var i = 0; i < message.contracts.length; ++i) + if (!$util.isString(message.contracts[i])) + return "contracts: string[] expected"; + } + return null; + }; + + /** + * Creates a ClusterInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof pruntime_rpc.ClusterInfo + * @static + * @param {Object.} object Plain object + * @returns {pruntime_rpc.ClusterInfo} ClusterInfo + */ + ClusterInfo.fromObject = function fromObject(object) { + if (object instanceof $root.pruntime_rpc.ClusterInfo) + return object; + var message = new $root.pruntime_rpc.ClusterInfo(); + if (object.id != null) + message.id = String(object.id); + if (object.version != null) + message.version = String(object.version); + if (object.stateRoot != null) + message.stateRoot = String(object.stateRoot); + if (object.contracts) { + if (!Array.isArray(object.contracts)) + throw TypeError(".pruntime_rpc.ClusterInfo.contracts: array expected"); + message.contracts = []; + for (var i = 0; i < object.contracts.length; ++i) + message.contracts[i] = String(object.contracts[i]); + } + return message; + }; + + /** + * Creates a plain object from a ClusterInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof pruntime_rpc.ClusterInfo + * @static + * @param {pruntime_rpc.ClusterInfo} message ClusterInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ClusterInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.contracts = []; + if (options.defaults) { + object.id = ""; + object.version = ""; + object.stateRoot = ""; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.version != null && message.hasOwnProperty("version")) + object.version = message.version; + if (message.stateRoot != null && message.hasOwnProperty("stateRoot")) + object.stateRoot = message.stateRoot; + if (message.contracts && message.contracts.length) { + object.contracts = []; + for (var j = 0; j < message.contracts.length; ++j) + object.contracts[j] = message.contracts[j]; + } + return object; + }; + + /** + * Converts this ClusterInfo to JSON. + * @function toJSON + * @memberof pruntime_rpc.ClusterInfo + * @instance + * @returns {Object.} JSON object + */ + ClusterInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ClusterInfo; + })(); + return pruntime_rpc; })(); diff --git a/e2e/src/utils/pruntime.js b/e2e/src/utils/pruntime.js index 1fb322da1f..727c103e7b 100644 --- a/e2e/src/utils/pruntime.js +++ b/e2e/src/utils/pruntime.js @@ -1,28 +1,32 @@ const axios = require('axios'); -const {pruntime_rpc} = require('../proto/pruntime_rpc'); +const { pruntime_rpc } = require('../proto/pruntime_rpc'); // TODO: make it a library (copied from scripts/js/console.js) class PRuntimeApi { constructor(endpoint) { this.uri = endpoint; - this.api = axios.create({ + const client = axios.create({ baseURL: endpoint, headers: { 'Content-Type': 'application/octet-stream', }, responseType: 'arraybuffer', }); - } - async req(method, data = undefined) { - const r = await this.api.post('/prpc/' + method, data); - return pruntime_rpc.PhactoryInfo.decode(r.data); - } - async query(_contractId, _request) { - throw new Error('Unimplemented'); + this.rpc = new pruntime_rpc.PhactoryAPI((method, data, callback) => { + client.post('/prpc/PhactoryAPI.' + method.name, data) + .then((r) => callback(null, r.data)) + .catch((error) => callback(error)) + }); } async getInfo() { - return await this.req('PhactoryAPI.GetInfo'); + return await this.rpc.getInfo({}); + } + + async getContractInfo(contractId) { + const contractIds = [contractId]; + const { contracts } = await this.rpc.getContractInfo({ contractIds }); + return contracts[0]; } } diff --git a/pallets/phala/Cargo.toml b/pallets/phala/Cargo.toml index 66611572aa..325994a8b3 100644 --- a/pallets/phala/Cargo.toml +++ b/pallets/phala/Cargo.toml @@ -50,6 +50,7 @@ frame-support-test = { git = "https://github.com/paritytech/substrate", branch = assert_matches = "1.4.0" pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } rand = "0.8.5" +insta = "1" [features] default = ["std"] diff --git a/pallets/phala/src/fat.rs b/pallets/phala/src/fat.rs index a4360028ec..c2452353ae 100644 --- a/pallets/phala/src/fat.rs +++ b/pallets/phala/src/fat.rs @@ -393,6 +393,12 @@ pub mod pallet { } Ok(()) } + + pub fn get_system_contract(contract: &ContractId) -> Option { + let contract_info = Contracts::::get(&contract)?; + let cluster_info = Clusters::::get(&contract_info.cluster_id)?; + Some(cluster_info.system_contract) + } } #[pallet::hooks] diff --git a/pallets/phala/src/fat_tokenomic.rs b/pallets/phala/src/fat_tokenomic.rs new file mode 100644 index 0000000000..42c839ea03 --- /dev/null +++ b/pallets/phala/src/fat_tokenomic.rs @@ -0,0 +1,154 @@ +//! The Fat Contract tokenomic module + +pub use self::pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use crate::mq::MessageOriginInfo; + use frame_support::{ + dispatch::DispatchResult, + pallet_prelude::*, + traits::{Currency, ExistenceRequirement::*, StorageVersion}, + PalletId, + }; + use frame_system::pallet_prelude::*; + use phala_types::messaging::ContractId; + use sp_runtime::traits::{AccountIdConversion, Zero}; + + type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + + const PALLET_ID: PalletId = PalletId(*b"phat/tok"); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type Currency: Currency; + } + + const STORAGE_VERSION: StorageVersion = StorageVersion::new(5); + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + /// Stake of user to contract + #[pallet::storage] + pub type ContractUserStakes = StorageDoubleMap< + _, + Twox64Concat, + T::AccountId, + Twox64Concat, + ContractId, + BalanceOf, + ValueQuery, + >; + + /// Map of contracts to their total stakes received + #[pallet::storage] + pub type ContractTotalStakes = + StorageMap<_, Twox64Concat, ContractId, BalanceOf, ValueQuery>; + + /// Minimum allowed stake + #[pallet::storage] + pub type MinStake = StorageValue<_, BalanceOf, ValueQuery>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + ContractDepositChanged { + contract: ContractId, + deposit: BalanceOf, + }, + UserStakeChanged { + account: T::AccountId, + contract: ContractId, + stake: BalanceOf, + }, + } + + #[pallet::error] + pub enum Error { + InvalidAmountOfStake, + } + + #[pallet::call] + impl Pallet + where + T: crate::mq::Config, + T: crate::fat::Config, + { + /// Adjust stake to given contract. + /// + /// Fat contracts accept depoits from accounts. The deposit info would be sent the cluster's + /// system contract. Then the system contract would invoke the driver contract (if installed) + /// to process the deposit info. A public good cluster usually would set the contracts' scheduling + /// weights according to the total depoit on contracts. More weights means it would get more + /// compute resource to run the contract. The weights are applied on contract query and Sidevm + /// CPU round scheduling. + /// + /// If users stake on a contract doesn't deployed yet. The deposit would send to the cluster + /// even if the contract is deployed later. User can re-stake with or without changing the amount + /// to sync the depoit the the cluster after the contract is actually deployed. + #[pallet::weight(0)] + pub fn adjust_stake( + origin: OriginFor, + contract: ContractId, + amount: BalanceOf, + ) -> DispatchResult { + let user = ensure_signed(origin)?; + ensure!( + amount == Zero::zero() || amount >= MinStake::::get(), + Error::::InvalidAmountOfStake + ); + + let mut total = ContractTotalStakes::::get(&contract); + let orig = ContractUserStakes::::get(&user, &contract); + if amount > orig { + let delta = amount - orig; + total += delta; + ::Currency::transfer(&user, &Self::pallet_id(), delta, KeepAlive)?; + } else { + let delta = orig - amount; + total -= delta; + ::Currency::transfer(&Self::pallet_id(), &user, delta, AllowDeath)?; + } + ContractUserStakes::::insert(&user, &contract, amount); + ContractTotalStakes::::insert(contract, total); + + Self::deposit_event(Event::ContractDepositChanged { + contract, + deposit: total, + }); + + Self::deposit_event(Event::UserStakeChanged { + account: user, + contract, + stake: amount, + }); + + if let Some(the_system_contract) = + crate::fat::Pallet::::get_system_contract(&contract) + { + let selector: u32 = 0xa24bcb44; // ContractDeposit::change_deposit() + let message = (selector.to_be_bytes(), contract, total).encode(); + Self::push_ink_message(the_system_contract, message); + } + Ok(()) + } + } + + impl Pallet { + fn pallet_id() -> T::AccountId { + PALLET_ID.into_account_truncating() + } + } + + impl MessageOriginInfo for Pallet { + type Config = T; + } +} + +#[cfg(test)] +mod tests; diff --git a/pallets/phala/src/fat_tokenomic/snapshots/phala_pallets__fat_tokenomic__tests__can_restake_without_any_changes-2.snap b/pallets/phala/src/fat_tokenomic/snapshots/phala_pallets__fat_tokenomic__tests__can_restake_without_any_changes-2.snap new file mode 100644 index 0000000000..ac7d49eb24 --- /dev/null +++ b/pallets/phala/src/fat_tokenomic/snapshots/phala_pallets__fat_tokenomic__tests__can_restake_without_any_changes-2.snap @@ -0,0 +1,20 @@ +--- +source: pallets/phala/src/fat_tokenomic/tests.rs +assertion_line: 98 +expression: events +--- +[ + RuntimeEvent::FatTokenomic( + Event::ContractDepositChanged { + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + deposit: 1000000000000, + }, + ), + RuntimeEvent::FatTokenomic( + Event::UserStakeChanged { + account: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + stake: 1000000000000, + }, + ), +] diff --git a/pallets/phala/src/fat_tokenomic/snapshots/phala_pallets__fat_tokenomic__tests__can_restake_without_any_changes.snap b/pallets/phala/src/fat_tokenomic/snapshots/phala_pallets__fat_tokenomic__tests__can_restake_without_any_changes.snap new file mode 100644 index 0000000000..804ba14597 --- /dev/null +++ b/pallets/phala/src/fat_tokenomic/snapshots/phala_pallets__fat_tokenomic__tests__can_restake_without_any_changes.snap @@ -0,0 +1,74 @@ +--- +source: pallets/phala/src/fat_tokenomic/tests.rs +assertion_line: 90 +expression: events +--- +[ + RuntimeEvent::System( + Event::NewAccount { + account: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + }, + ), + RuntimeEvent::Balances( + Event::Endowed { + account: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + free_balance: 100000000000000, + }, + ), + RuntimeEvent::Balances( + Event::BalanceSet { + who: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + free: 100000000000000, + reserved: 0, + }, + ), + RuntimeEvent::System( + Event::NewAccount { + account: 0202020202020202020202020202020202020202020202020202020202020202 (5C7LYpP2...), + }, + ), + RuntimeEvent::Balances( + Event::Endowed { + account: 0202020202020202020202020202020202020202020202020202020202020202 (5C7LYpP2...), + free_balance: 100000000000000, + }, + ), + RuntimeEvent::Balances( + Event::BalanceSet { + who: 0202020202020202020202020202020202020202020202020202020202020202 (5C7LYpP2...), + free: 100000000000000, + reserved: 0, + }, + ), + RuntimeEvent::System( + Event::NewAccount { + account: 6d6f646c706861742f746f6b0000000000000000000000000000000000000000 (5EYCAe5i...), + }, + ), + RuntimeEvent::Balances( + Event::Endowed { + account: 6d6f646c706861742f746f6b0000000000000000000000000000000000000000 (5EYCAe5i...), + free_balance: 1000000000000, + }, + ), + RuntimeEvent::Balances( + Event::Transfer { + from: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + to: 6d6f646c706861742f746f6b0000000000000000000000000000000000000000 (5EYCAe5i...), + amount: 1000000000000, + }, + ), + RuntimeEvent::FatTokenomic( + Event::ContractDepositChanged { + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + deposit: 1000000000000, + }, + ), + RuntimeEvent::FatTokenomic( + Event::UserStakeChanged { + account: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + stake: 1000000000000, + }, + ), +] diff --git a/pallets/phala/src/fat_tokenomic/snapshots/phala_pallets__fat_tokenomic__tests__should_be_happy_to_stake.snap b/pallets/phala/src/fat_tokenomic/snapshots/phala_pallets__fat_tokenomic__tests__should_be_happy_to_stake.snap new file mode 100644 index 0000000000..8d878b8d05 --- /dev/null +++ b/pallets/phala/src/fat_tokenomic/snapshots/phala_pallets__fat_tokenomic__tests__should_be_happy_to_stake.snap @@ -0,0 +1,139 @@ +--- +source: pallets/phala/src/fat_tokenomic/tests.rs +assertion_line: 64 +expression: events +--- +[ + RuntimeEvent::System( + Event::NewAccount { + account: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + }, + ), + RuntimeEvent::Balances( + Event::Endowed { + account: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + free_balance: 100000000000000, + }, + ), + RuntimeEvent::Balances( + Event::BalanceSet { + who: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + free: 100000000000000, + reserved: 0, + }, + ), + RuntimeEvent::System( + Event::NewAccount { + account: 0202020202020202020202020202020202020202020202020202020202020202 (5C7LYpP2...), + }, + ), + RuntimeEvent::Balances( + Event::Endowed { + account: 0202020202020202020202020202020202020202020202020202020202020202 (5C7LYpP2...), + free_balance: 100000000000000, + }, + ), + RuntimeEvent::Balances( + Event::BalanceSet { + who: 0202020202020202020202020202020202020202020202020202020202020202 (5C7LYpP2...), + free: 100000000000000, + reserved: 0, + }, + ), + RuntimeEvent::System( + Event::NewAccount { + account: 6d6f646c706861742f746f6b0000000000000000000000000000000000000000 (5EYCAe5i...), + }, + ), + RuntimeEvent::Balances( + Event::Endowed { + account: 6d6f646c706861742f746f6b0000000000000000000000000000000000000000 (5EYCAe5i...), + free_balance: 1000000000000, + }, + ), + RuntimeEvent::Balances( + Event::Transfer { + from: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + to: 6d6f646c706861742f746f6b0000000000000000000000000000000000000000 (5EYCAe5i...), + amount: 1000000000000, + }, + ), + RuntimeEvent::FatTokenomic( + Event::ContractDepositChanged { + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + deposit: 1000000000000, + }, + ), + RuntimeEvent::FatTokenomic( + Event::UserStakeChanged { + account: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + stake: 1000000000000, + }, + ), + RuntimeEvent::Balances( + Event::Transfer { + from: 0202020202020202020202020202020202020202020202020202020202020202 (5C7LYpP2...), + to: 6d6f646c706861742f746f6b0000000000000000000000000000000000000000 (5EYCAe5i...), + amount: 2000000000000, + }, + ), + RuntimeEvent::FatTokenomic( + Event::ContractDepositChanged { + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + deposit: 3000000000000, + }, + ), + RuntimeEvent::FatTokenomic( + Event::UserStakeChanged { + account: 0202020202020202020202020202020202020202020202020202020202020202 (5C7LYpP2...), + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + stake: 2000000000000, + }, + ), + RuntimeEvent::Balances( + Event::Transfer { + from: 6d6f646c706861742f746f6b0000000000000000000000000000000000000000 (5EYCAe5i...), + to: 0202020202020202020202020202020202020202020202020202020202020202 (5C7LYpP2...), + amount: 2000000000000, + }, + ), + RuntimeEvent::FatTokenomic( + Event::ContractDepositChanged { + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + deposit: 1000000000000, + }, + ), + RuntimeEvent::FatTokenomic( + Event::UserStakeChanged { + account: 0202020202020202020202020202020202020202020202020202020202020202 (5C7LYpP2...), + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + stake: 0, + }, + ), + RuntimeEvent::System( + Event::KilledAccount { + account: 6d6f646c706861742f746f6b0000000000000000000000000000000000000000 (5EYCAe5i...), + }, + ), + RuntimeEvent::Balances( + Event::Transfer { + from: 6d6f646c706861742f746f6b0000000000000000000000000000000000000000 (5EYCAe5i...), + to: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + amount: 1000000000000, + }, + ), + RuntimeEvent::FatTokenomic( + Event::ContractDepositChanged { + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + deposit: 0, + }, + ), + RuntimeEvent::FatTokenomic( + Event::UserStakeChanged { + account: 0101010101010101010101010101010101010101010101010101010101010101 (5C62Ck4U...), + contract: 0x2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, + stake: 0, + }, + ), +] diff --git a/pallets/phala/src/fat_tokenomic/tests.rs b/pallets/phala/src/fat_tokenomic/tests.rs new file mode 100644 index 0000000000..cf30cad4cd --- /dev/null +++ b/pallets/phala/src/fat_tokenomic/tests.rs @@ -0,0 +1,100 @@ +use super::*; +use frame_support::{assert_err, assert_ok}; +use mock::{RuntimeOrigin as Origin, Test, DOLLARS}; + +use sp_core::crypto::AccountId32; +use sp_core::H256; + +mod mock; + +const ALICE: AccountId32 = AccountId32::new([1u8; 32]); +const BOB: AccountId32 = AccountId32::new([2u8; 32]); +const CONTRACT: H256 = H256([42u8; 32]); + +macro_rules! stake { + ($user: expr, $amount: expr) => { + Pallet::::adjust_stake(Origin::signed($user), CONTRACT, $amount) + }; +} + +fn stake_of_contract() -> u128 { + ContractTotalStakes::::get(&CONTRACT) +} + +fn stake_of_user(user: &AccountId32) -> u128 { + ContractUserStakes::::get(user, &CONTRACT) +} + +fn balance_of_user(user: &AccountId32) -> u128 { + mock::System::account(user).data.free +} + +fn prapare() { + mock::System::set_block_number(1); + mock::Balances::set_balance(Origin::root(), ALICE, 100 * DOLLARS, 0).unwrap(); + mock::Balances::set_balance(Origin::root(), BOB, 100 * DOLLARS, 0).unwrap(); + MinStake::::put(1 * DOLLARS); +} + +#[test] +fn should_be_happy_to_stake() { + mock::new_test_ext().execute_with(|| { + prapare(); + assert_ok!(stake!(ALICE, 1 * DOLLARS)); + assert_eq!(stake_of_user(&ALICE), 1 * DOLLARS); + assert_eq!(stake_of_user(&BOB), 0); + assert_eq!(stake_of_contract(), 1 * DOLLARS); + assert_eq!(balance_of_user(&ALICE), 99 * DOLLARS); + + assert_ok!(stake!(BOB, 2 * DOLLARS)); + assert_eq!(stake_of_user(&ALICE), 1 * DOLLARS); + assert_eq!(stake_of_user(&BOB), 2 * DOLLARS); + assert_eq!(stake_of_contract(), 3 * DOLLARS); + assert_eq!(balance_of_user(&BOB), 98 * DOLLARS); + + assert_ok!(stake!(BOB, 0)); + assert_ok!(stake!(ALICE, 0)); + assert_eq!(stake_of_user(&ALICE), 0); + assert_eq!(stake_of_user(&BOB), 0); + assert_eq!(stake_of_contract(), 0); + assert_eq!(balance_of_user(&ALICE), 100 * DOLLARS); + assert_eq!(balance_of_user(&BOB), 100 * DOLLARS); + + let events = mock::take_events(); + insta::assert_debug_snapshot!(events); + }); +} + +#[test] +fn can_not_stake_less_than_minstake() { + mock::new_test_ext().execute_with(|| { + prapare(); + assert_err!( + stake!(ALICE, DOLLARS - 1), + Error::::InvalidAmountOfStake + ); + }); +} + +#[test] +fn can_restake_without_any_changes() { + mock::new_test_ext().execute_with(|| { + prapare(); + + assert_ok!(stake!(ALICE, 1 * DOLLARS)); + assert_eq!(stake_of_user(&ALICE), 1 * DOLLARS); + assert_eq!(stake_of_contract(), 1 * DOLLARS); + assert_eq!(balance_of_user(&ALICE), 99 * DOLLARS); + + let events = mock::take_events(); + insta::assert_debug_snapshot!(events); + + assert_ok!(stake!(ALICE, 1 * DOLLARS)); + assert_eq!(stake_of_user(&ALICE), 1 * DOLLARS); + assert_eq!(stake_of_contract(), 1 * DOLLARS); + assert_eq!(balance_of_user(&ALICE), 99 * DOLLARS); + + let events = mock::take_events(); + insta::assert_debug_snapshot!(events); + }); +} diff --git a/pallets/phala/src/fat_tokenomic/tests/mock.rs b/pallets/phala/src/fat_tokenomic/tests/mock.rs new file mode 100644 index 0000000000..ed7082b9c1 --- /dev/null +++ b/pallets/phala/src/fat_tokenomic/tests/mock.rs @@ -0,0 +1,173 @@ +use crate::{ + attestation::{Attestation, AttestationValidator, Error as AttestationError, IasFields}, + fat, fat_tokenomic, mq, registry, +}; + +use frame_support::{pallet_prelude::ConstU32, parameter_types, traits::GenesisBuild}; +use frame_system as system; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; + +pub(crate) type Balance = u128; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; +pub(crate) type BlockNumber = u64; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + // Phala pallets + PhalaMq: mq::{Pallet, Call}, + PhalaRegistry: registry::{Pallet, Event, Storage, Config}, + FatContracts: fat, + FatTokenomic: fat_tokenomic, + } +); + +parameter_types! { + pub const ExistentialDeposit: u64 = 2; + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 20; + pub const MinimumPeriod: u64 = 1; + pub const VerifyPRuntime: bool = false; + pub const VerifyRelaychainGenesisBlockHash: bool = true; +} +impl system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Index = u64; + type BlockNumber = BlockNumber; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = sp_core::crypto::AccountId32; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = ConstU32<2>; +} + +impl pallet_balances::Config for Test { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; +} + +impl pallet_timestamp::Config for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +pub const DOLLARS: Balance = 1_000_000_000_000; + +impl mq::Config for Test { + type QueueNotifyConfig = (); + type CallMatcher = MqCallMatcher; +} + +pub struct MqCallMatcher; +impl mq::CallMatcher for MqCallMatcher { + fn match_call(call: &RuntimeCall) -> Option<&mq::Call> { + match call { + RuntimeCall::PhalaMq(mq_call) => Some(mq_call), + _ => None, + } + } +} + +impl registry::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type AttestationValidator = MockValidator; + type UnixTime = Timestamp; + type VerifyPRuntime = VerifyPRuntime; + type VerifyRelaychainGenesisBlockHash = VerifyRelaychainGenesisBlockHash; + type GovernanceOrigin = frame_system::EnsureRoot; +} + +impl fat::Config for Test { + type RuntimeEvent = RuntimeEvent; + type InkCodeSizeLimit = ConstU32<{ 1024 * 1024 }>; + type SidevmCodeSizeLimit = ConstU32<{ 1024 * 1024 }>; +} + +impl fat_tokenomic::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; +} + +pub struct MockValidator; +impl AttestationValidator for MockValidator { + fn validate( + _attestation: &Attestation, + _user_data_hash: &[u8; 32], + _now: u64, + _verify_pruntime: bool, + _pruntime_allowlist: Vec>, + ) -> Result { + Ok(IasFields { + mr_enclave: [0u8; 32], + mr_signer: [0u8; 32], + isv_prod_id: [0u8; 2], + isv_svn: [0u8; 2], + report_data: [0u8; 64], + confidence_level: 128u8, + }) + } +} + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = system::GenesisConfig::default() + .build_storage::() + .unwrap(); + let zero_pubkey = sp_core::sr25519::Public::from_raw([0u8; 32]); + let zero_ecdh_pubkey = Vec::from(&[0u8; 32][..]); + crate::registry::GenesisConfig:: { + workers: vec![(zero_pubkey.clone(), zero_ecdh_pubkey, None)], + gatekeepers: vec![(zero_pubkey.clone())], + benchmark_duration: 0u32, + } + .assimilate_storage(&mut t) + .unwrap(); + sp_io::TestExternalities::new(t) +} + +pub fn take_events() -> Vec { + let evt = System::events() + .into_iter() + .map(|evt| evt.event) + .collect(); + System::reset_events(); + evt +} diff --git a/pallets/phala/src/lib.rs b/pallets/phala/src/lib.rs index 9de173c888..57965e6e68 100644 --- a/pallets/phala/src/lib.rs +++ b/pallets/phala/src/lib.rs @@ -17,6 +17,7 @@ pub mod migrations; pub mod utils; pub mod fat; +pub mod fat_tokenomic; pub mod mining; pub mod mq; pub mod ott; @@ -26,6 +27,7 @@ pub mod stakepool; // Alias pub use fat as pallet_fat; +pub use fat_tokenomic as pallet_fat_tokenomic; pub use mining as pallet_mining; pub use mq as pallet_mq; pub use ott as pallet_ott; diff --git a/pallets/phala/src/migrations/mod.rs b/pallets/phala/src/migrations/mod.rs index 8ffda3f9a3..5dd9f40857 100644 --- a/pallets/phala/src/migrations/mod.rs +++ b/pallets/phala/src/migrations/mod.rs @@ -14,10 +14,10 @@ type MiningBalanceOf = /// Alias for the runtime that implements all Phala Pallets pub trait PhalaPallets: - fat::Config + mining::Config + mq::Config + registry::Config + stakepool::Config + fat::Config + mining::Config + mq::Config + registry::Config + stakepool::Config + fat_tokenomic::Config {} impl PhalaPallets for T where - T: fat::Config + mining::Config + mq::Config + registry::Config + stakepool::Config + T: fat::Config + mining::Config + mq::Config + registry::Config + stakepool::Config + fat_tokenomic::Config {} type Versions = ( @@ -26,6 +26,7 @@ type Versions = ( StorageVersion, StorageVersion, StorageVersion, + StorageVersion, ); #[allow(dead_code)] @@ -36,6 +37,7 @@ fn get_versions() -> Versions { StorageVersion::get::>(), StorageVersion::get::>(), StorageVersion::get::>(), + StorageVersion::get::>(), ) } @@ -47,6 +49,7 @@ fn unified_versions(version: u16) -> Versions { StorageVersion::new(version), StorageVersion::new(version), StorageVersion::new(version), + StorageVersion::new(version), ) } @@ -57,4 +60,5 @@ fn set_unified_version(version: u16) { StorageVersion::new(version).put::>(); StorageVersion::new(version).put::>(); StorageVersion::new(version).put::>(); + StorageVersion::new(version).put::>(); } diff --git a/standalone/pruntime/Cargo.lock b/standalone/pruntime/Cargo.lock index b47b89aeef..9332db72ec 100644 --- a/standalone/pruntime/Cargo.lock +++ b/standalone/pruntime/Cargo.lock @@ -6101,6 +6101,7 @@ version = "0.1.0" dependencies = [ "anyhow", "dashmap", + "derive_more 0.99.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures", "hex_fmt", "libc", diff --git a/standalone/pruntime/Makefile b/standalone/pruntime/Makefile index df7c1f92dd..f2554552c7 100644 --- a/standalone/pruntime/Makefile +++ b/standalone/pruntime/Makefile @@ -1,3 +1,5 @@ +SGX_MODE ?= SW + .PHONY: all clean ifeq ($(SGX_MODE),SW) all: bin/Rocket.toml bin/app diff --git a/standalone/pruntime/src/api_server.rs b/standalone/pruntime/src/api_server.rs index 2edff91e66..54e18f8157 100644 --- a/standalone/pruntime/src/api_server.rs +++ b/standalone/pruntime/src/api_server.rs @@ -146,6 +146,16 @@ fn getinfo() -> String { runtime::ecall_getinfo() } +#[get("/contract_info?")] +fn get_contract_info(id: Option) -> String { + runtime::ecall_get_contract_info(&id.unwrap_or_default()) +} + +#[get("/cluster_info")] +fn get_cluster_info() -> String { + runtime::ecall_get_cluster_info() +} + fn default_payload_limit_for_method(method: PhactoryAPIMethod) -> ByteUnit { use PhactoryAPIMethod::*; @@ -172,6 +182,8 @@ fn default_payload_limit_for_method(method: PhactoryAPIMethod) -> ByteUnit { SignEndpointInfo => 32.kibibytes(), ConfigNetwork => 10.kibibytes(), HttpFetch => 100.mebibytes(), + GetContractInfo => 100.kibibytes(), + GetClusterInfo => 1.kibibytes(), } } @@ -210,7 +222,12 @@ async fn prpc_proxy(method: String, data: Data<'_>, limits: &Limits) -> Custom", data = "")] async fn prpc_proxy_acl(method: String, data: Data<'_>, limits: &Limits) -> Custom> { info!("prpc_acl: request {}:", method); - let permitted_method = ["PhactoryAPI.ContractQuery", "PhactoryAPI.GetInfo"]; + let permitted_method = [ + "PhactoryAPI.ContractQuery", + "PhactoryAPI.GetInfo", + "PhactoryAPI.GetContractInfo", + "PhactoryAPI.GetClusterInfo", + ]; if !permitted_method.contains(&&method[..]) { error!("prpc_acl: access denied"); return Custom(Status::Forbidden, vec![]); @@ -273,7 +290,7 @@ pub(super) fn rocket(args: &super::Args) -> rocket::Rocket { ), ], ) - .mount("/", routes![getinfo]); + .mount("/", routes![getinfo, get_contract_info, get_cluster_info]); if args.enable_kick_api { info!("ENABLE `kick` API"); @@ -314,8 +331,8 @@ pub(super) fn rocket_acl(args: &super::Args) -> Option Option = RpcService::new(GraminePlatform); @@ -15,7 +15,34 @@ pub fn ecall_handle(action: u8, input: &[u8]) -> Result> { } pub fn ecall_getinfo() -> String { - APPLICATION.lock_phactory().getinfo() + let info = APPLICATION.lock_phactory().get_info(); + serde_json::to_string_pretty(&info).unwrap_or_default() +} + +fn serialize_result(result: Result) -> String { + match result { + Ok(inner) => serde_json::to_string_pretty(&inner).unwrap_or_default(), + Err(err) => { + let error = format!("{:?}", err); + serde_json::to_string_pretty(&serde_json::json!({ "error": error })) + } + .unwrap_or_default(), + } +} + +pub fn ecall_get_contract_info(ids: &str) -> String { + let ids = if ids.is_empty() { + vec![] + } else { + ids.split(",").map(|it| it.to_owned()).collect() + }; + let result = APPLICATION.lock_phactory().get_contract_info(&ids); + serialize_result(result.map(|it| it.contracts)) +} + +pub fn ecall_get_cluster_info() -> String { + let result = APPLICATION.lock_phactory().get_cluster_info(); + serialize_result(result.map(|it| it.clusters)) } pub fn ecall_sign_http_response(data: &[u8]) -> Option { diff --git a/standalone/runtime/src/lib.rs b/standalone/runtime/src/lib.rs index f8c353e79b..c3cdc54207 100644 --- a/standalone/runtime/src/lib.rs +++ b/standalone/runtime/src/lib.rs @@ -111,6 +111,7 @@ pub use phala_pallets::{ pallet_mining, pallet_stakepool, pallet_fat, + pallet_fat_tokenomic, puppets, }; @@ -1320,6 +1321,11 @@ impl pallet_fat::Config for Runtime { type SidevmCodeSizeLimit = ConstU32<{1024*1024*8}>; } +impl pallet_fat_tokenomic::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; +} + impl puppets::parachain_info::Config for Runtime {} impl puppets::parachain_system::Config for Runtime {} @@ -1374,6 +1380,7 @@ construct_runtime!( PhalaMining: pallet_mining, PhalaStakePool: pallet_stakepool, PhalaFatContracts: pallet_fat, + PhalaFatTokenomic: pallet_fat_tokenomic, // Put them here to make sure pherry could be compiled with phala's metadata. ParachainInfo: puppets::parachain_info,