From 9c07654407d72cda86b5bdf1ece05d09fefaf820 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Thu, 23 Jan 2025 15:46:53 +0000 Subject: [PATCH 01/18] SystemAPI trait --- rs/interfaces/src/execution_environment.rs | 78 ++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/rs/interfaces/src/execution_environment.rs b/rs/interfaces/src/execution_environment.rs index 970adef0fd3..d18d57b7b65 100644 --- a/rs/interfaces/src/execution_environment.rs +++ b/rs/interfaces/src/execution_environment.rs @@ -1172,6 +1172,84 @@ pub trait SystemApi { dst: usize, heap: &mut [u8], ) -> HypervisorResult<()>; + + /// Returns the replication factor of the provided subnet. + /// + /// Traps if `src`/`size` are not a valid encoding of a principal, or if + /// the principal is not a subnet. + fn ic0_replication_factor(&self, src: usize, size: usize, heap: &[u8]) + -> HypervisorResult; + + /// This system call indicates the cycle cost of an inter-canister call, + /// i.e., `ic0.call_perform` + /// + /// The amount of cycles is represented by a 128-bit value and is copied + /// to the canister memory starting at the location `dst`. + fn ic0_cost_call( + &self, + num_req_bytes: u64, + dst: usize, + heap: &mut [u8], + ) -> HypervisorResult<()>; + + /// This system call indicates the cycle cost of creating a canister on + /// the same subnet, i.e., the management canister's `create_canister`. + /// + /// The amount of cycles is represented by a 128-bit value and is copied + /// to the canister memory starting at the location `dst`. + fn ic0_cost_create_canister(&self, dst: usize, heap: &mut [u8]) -> HypervisorResult<()>; + + /// This system call indicates the cycle cost of making an http outcall, + /// i.e., the management canister's `http_request`. + /// + /// The amount of cycles is represented by a 128-bit value and is copied + /// to the canister memory starting at the location `dst`. + fn ic0_cost_http_request( + &self, + num_req_bytes: u64, + num_res_bytes: u64, + dst: usize, + heap: &mut [u8], + ) -> HypervisorResult<()>; + + /// This system call indicates the cycle cost of signing with ecdsa, + /// i.e., the management canister's `sign_with_ecdsa`. + /// + /// The amount of cycles is represented by a 128-bit value and is copied + /// to the canister memory starting at the location `dst`. + fn ic0_cost_ecdsa( + &self, + src: usize, + size: usize, + dst: usize, + heap: &mut [u8], + ) -> HypervisorResult<()>; + + /// This system call indicates the cycle cost of signing with schnorr, + /// i.e., the management canister's `sign_with_schnorr`. + /// + /// The amount of cycles is represented by a 128-bit value and is copied + /// to the canister memory starting at the location `dst`. + fn ic0_cost_schnorr( + &self, + src: usize, + size: usize, + dst: usize, + heap: &mut [u8], + ) -> HypervisorResult<()>; + + /// This system call indicates the cycle cost of signing with ecdsa, + /// i.e., the management canister's `vetkd_encrypted_key`. + /// + /// The amount of cycles is represented by a 128-bit value and is copied + /// to the canister memory starting at the location `dst`. + fn ic0_cost_vetkey( + &self, + src: usize, + size: usize, + dst: usize, + heap: &mut [u8], + ) -> HypervisorResult<()>; } #[derive(Copy, Clone, Eq, PartialEq, Debug)] From 77c3096479bf000b63a4cb2020a54568e09e75ad Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 28 Jan 2025 10:07:32 +0000 Subject: [PATCH 02/18] SystemAPI trait changes --- rs/interfaces/src/execution_environment.rs | 32 +++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/rs/interfaces/src/execution_environment.rs b/rs/interfaces/src/execution_environment.rs index d18d57b7b65..3f2afe6f6e9 100644 --- a/rs/interfaces/src/execution_environment.rs +++ b/rs/interfaces/src/execution_environment.rs @@ -1181,13 +1181,17 @@ pub trait SystemApi { -> HypervisorResult; /// This system call indicates the cycle cost of an inter-canister call, - /// i.e., `ic0.call_perform` + /// i.e., `ic0.call_perform`. + /// + /// The cost is determined by the byte length of the method name and the + /// length of the encoded payload. /// /// The amount of cycles is represented by a 128-bit value and is copied /// to the canister memory starting at the location `dst`. fn ic0_cost_call( &self, - num_req_bytes: u64, + method_name_size: u64, + payload_size: u64, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()>; @@ -1202,18 +1206,26 @@ pub trait SystemApi { /// This system call indicates the cycle cost of making an http outcall, /// i.e., the management canister's `http_request`. /// + /// `request_size` is the sum of the lengths of the variable request parts, as + /// documented in the interface specification. + /// `max_res_bytes` is the maximum number of response bytes the caller wishes to + /// accept. + /// /// The amount of cycles is represented by a 128-bit value and is copied /// to the canister memory starting at the location `dst`. fn ic0_cost_http_request( &self, - num_req_bytes: u64, - num_res_bytes: u64, + request_size: u64, + max_res_bytes: u64, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()>; /// This system call indicates the cycle cost of signing with ecdsa, - /// i.e., the management canister's `sign_with_ecdsa`. + /// i.e., the management canister's `sign_with_ecdsa`, for the key + /// with name given by `src` + `size`. + /// + /// Traps if `src`/`size` cannot be decoded to a valid key name. /// /// The amount of cycles is represented by a 128-bit value and is copied /// to the canister memory starting at the location `dst`. @@ -1226,7 +1238,10 @@ pub trait SystemApi { ) -> HypervisorResult<()>; /// This system call indicates the cycle cost of signing with schnorr, - /// i.e., the management canister's `sign_with_schnorr`. + /// i.e., the management canister's `sign_with_schnorr` for the key + /// with name given by `src` + `size`. + /// + /// Traps if `src`/`size` cannot be decoded to a valid key name. /// /// The amount of cycles is represented by a 128-bit value and is copied /// to the canister memory starting at the location `dst`. @@ -1239,7 +1254,10 @@ pub trait SystemApi { ) -> HypervisorResult<()>; /// This system call indicates the cycle cost of signing with ecdsa, - /// i.e., the management canister's `vetkd_encrypted_key`. + /// i.e., the management canister's `vetkd_encrypted_key` for the key + /// with name given by `src` + `size`. + /// + /// Traps if `src`/`size` cannot be decoded to a valid key name. /// /// The amount of cycles is represented by a 128-bit value and is copied /// to the canister memory starting at the location `dst`. From 14e8d66be2365c02050f9a63fe40ec66a664625b Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 28 Jan 2025 19:38:14 +0000 Subject: [PATCH 03/18] implement key costs --- rs/replicated_state/src/metadata_state.rs | 14 ++ rs/system_api/src/lib.rs | 147 +++++++++++++++++- .../src/sandbox_safe_system_state.rs | 6 +- rs/types/management_canister_types/src/lib.rs | 8 + rs/types/types/src/consensus/idkg/common.rs | 11 ++ 5 files changed, 183 insertions(+), 3 deletions(-) diff --git a/rs/replicated_state/src/metadata_state.rs b/rs/replicated_state/src/metadata_state.rs index b77aa920c7f..36ba46482e1 100644 --- a/rs/replicated_state/src/metadata_state.rs +++ b/rs/replicated_state/src/metadata_state.rs @@ -29,6 +29,7 @@ use ic_registry_routing_table::{ }; use ic_registry_subnet_features::SubnetFeatures; use ic_registry_subnet_type::SubnetType; +use ic_types::consensus::idkg::common::SignatureScheme; use ic_types::{ batch::BlockmakerMetrics, crypto::CryptoHash, @@ -244,6 +245,19 @@ impl NetworkTopology { .get(subnet_id) .map(|subnet_topology| subnet_topology.nodes.len()) } + + pub fn get_key_by_name( + &self, + signature_scheme: SignatureScheme, + key_name: &str, + ) -> Option<&MasterPublicKeyId> { + for entry in self.chain_key_enabled_subnets.keys() { + if signature_scheme == entry.into() && key_name == entry.get_key_name() { + return Some(entry); + } + } + None + } } impl From<&NetworkTopology> for pb_metadata::NetworkTopology { diff --git a/rs/system_api/src/lib.rs b/rs/system_api/src/lib.rs index 1a30743355e..6466dfe218e 100644 --- a/rs/system_api/src/lib.rs +++ b/rs/system_api/src/lib.rs @@ -13,11 +13,12 @@ use ic_interfaces::execution_environment::{ use ic_logger::{error, ReplicaLogger}; use ic_registry_subnet_type::SubnetType; use ic_replicated_state::{ - canister_state::WASM_PAGE_SIZE_IN_BYTES, memory_required_to_push_request, Memory, NumWasmPages, - PageIndex, + canister_state::WASM_PAGE_SIZE_IN_BYTES, memory_required_to_push_request, Memory, + NetworkTopology, NumWasmPages, PageIndex, }; use ic_sys::PageBytes; use ic_types::{ + consensus::idkg::common::SignatureScheme, ingress::WasmResult, messages::{CallContextId, RejectContext, Request, MAX_INTER_CANISTER_PAYLOAD_IN_BYTES}, methods::{SystemMethod, WasmClosure}, @@ -36,6 +37,7 @@ use std::{ collections::BTreeMap, convert::{From, TryFrom}, rc::Rc, + str, }; pub mod cycles_balance_change; @@ -3541,6 +3543,147 @@ impl SystemApi for SystemApiImpl { trace_syscall!(self, CyclesBurn128, result, amount); result } + + fn ic0_replication_factor( + &self, + src: usize, + size: usize, + heap: &[u8], + ) -> HypervisorResult { + todo!() + } + + fn ic0_cost_call( + &self, + method_name_size: u64, + payload_size: u64, + dst: usize, + heap: &mut [u8], + ) -> HypervisorResult<()> { + todo!() + } + + fn ic0_cost_create_canister(&self, dst: usize, heap: &mut [u8]) -> HypervisorResult<()> { + // find own subnet repl factor; get fee, write to dst. + todo!() + } + + fn ic0_cost_http_request( + &self, + request_size: u64, + max_res_bytes: u64, + dst: usize, + heap: &mut [u8], + ) -> HypervisorResult<()> { + todo!() + } + + fn ic0_cost_ecdsa( + &self, + src: usize, + size: usize, + dst: usize, + heap: &mut [u8], + ) -> HypervisorResult<()> { + let topology = &self.sandbox_safe_system_state.network_topology; + let subnet_size = get_signing_key_replication_factor( + SignatureScheme::Ecdsa, + "ecdsa", + topology, + src, + size, + heap, + )?; + let cost = self + .sandbox_safe_system_state + .cycles_account_manager + .ecdsa_signature_fee(subnet_size); + copy_cycles_to_heap(cost, dst, heap, "ic0_cost_ecdsa")?; + Ok(()) + } + + fn ic0_cost_schnorr( + &self, + src: usize, + size: usize, + dst: usize, + heap: &mut [u8], + ) -> HypervisorResult<()> { + let topology = &self.sandbox_safe_system_state.network_topology; + let subnet_size = get_signing_key_replication_factor( + SignatureScheme::Schnorr, + "schnorr", + topology, + src, + size, + heap, + )?; + let cost = self + .sandbox_safe_system_state + .cycles_account_manager + .schnorr_signature_fee(subnet_size); + copy_cycles_to_heap(cost, dst, heap, "ic0_cost_schnorr")?; + Ok(()) + } + + fn ic0_cost_vetkey( + &self, + src: usize, + size: usize, + dst: usize, + heap: &mut [u8], + ) -> HypervisorResult<()> { + let topology = &self.sandbox_safe_system_state.network_topology; + let subnet_size = get_signing_key_replication_factor( + SignatureScheme::VetKd, + "vetkey", + topology, + src, + size, + heap, + )?; + let cost = self + .sandbox_safe_system_state + .cycles_account_manager + .vetkd_fee(subnet_size); + copy_cycles_to_heap(cost, dst, heap, "ic0_cost_vetkey")?; + Ok(()) + } +} + +/// Common steps for the syscalls `ic0_cost_ecdsa`, `ic0_cost_schnorr` and `ic0_cost_vetkey`. +/// Extract the key name, look it up in `chain_key_enabled_subnets`, then extract all subnets +/// for that key and return the replication factor of the biggest one. +fn get_signing_key_replication_factor( + scheme: SignatureScheme, + scheme_str: &str, + topology: &NetworkTopology, + src: usize, + size: usize, + heap: &mut [u8], +) -> HypervisorResult { + let key_bytes = valid_subslice(&format!("ic0.cost_{} heap", scheme_str), src, size, heap)?; + let key_name = + str::from_utf8(key_bytes).map_err(|_| HypervisorError::ToolchainContractViolation { + error: format!( + "Failed to decode key name {}", + String::from_utf8_lossy(key_bytes) + ), + })?; + let key_id = topology.get_key_by_name(scheme, key_name).ok_or( + HypervisorError::ToolchainContractViolation { + error: format!("{} signing key {} not known.", scheme, key_name), + }, + )?; + let max_subnet_size = topology + .chain_key_enabled_subnets(key_id) + .iter() // this is non-empty, otherwise key_id would have errored + .map(|subnet_id| { + topology.get_subnet_size(subnet_id).unwrap() // we got the subnet_id from the collection + }) + .max() + .unwrap(); // the maximum of a non-empty sequence of usize exists + Ok(max_subnet_size) } /// The default implementation of the `OutOfInstructionHandler` trait. diff --git a/rs/system_api/src/sandbox_safe_system_state.rs b/rs/system_api/src/sandbox_safe_system_state.rs index 1e9e6d31784..996df9bbe7f 100644 --- a/rs/system_api/src/sandbox_safe_system_state.rs +++ b/rs/system_api/src/sandbox_safe_system_state.rs @@ -576,7 +576,7 @@ pub struct SandboxSafeSystemState { reserved_balance_limit: Option, call_context_balance: Option, call_context_deadline: Option, - cycles_account_manager: CyclesAccountManager, + pub(super) cycles_account_manager: CyclesAccountManager, // None indicates that we are in a context where the canister cannot // register callbacks (e.g. running the `start` method when installing a // canister.) @@ -593,6 +593,7 @@ pub struct SandboxSafeSystemState { pub(super) request_metadata: RequestMetadata, caller: Option, pub is_wasm64_execution: bool, + pub(super) network_topology: NetworkTopology, } impl SandboxSafeSystemState { @@ -627,6 +628,7 @@ impl SandboxSafeSystemState { caller: Option, next_canister_log_record_idx: u64, is_wasm64_execution: bool, + network_topology: NetworkTopology, ) -> Self { Self { canister_id, @@ -662,6 +664,7 @@ impl SandboxSafeSystemState { request_metadata, caller, is_wasm64_execution, + network_topology, } } @@ -776,6 +779,7 @@ impl SandboxSafeSystemState { caller, system_state.canister_log.next_idx(), is_wasm64_execution, + network_topology.clone(), ) } diff --git a/rs/types/management_canister_types/src/lib.rs b/rs/types/management_canister_types/src/lib.rs index 7dcadcb9333..2d129793fcd 100644 --- a/rs/types/management_canister_types/src/lib.rs +++ b/rs/types/management_canister_types/src/lib.rs @@ -2490,6 +2490,14 @@ impl MasterPublicKeyId { Self::VetKd(_) => false, } } + + pub fn get_key_name(&self) -> &str { + match self { + MasterPublicKeyId::Ecdsa(EcdsaKeyId { name, .. }) => name, + MasterPublicKeyId::Schnorr(SchnorrKeyId { name, .. }) => name, + MasterPublicKeyId::VetKd(VetKdKeyId { name, .. }) => name, + } + } } impl FromStr for MasterPublicKeyId { diff --git a/rs/types/types/src/consensus/idkg/common.rs b/rs/types/types/src/consensus/idkg/common.rs index 9409a4b0fa4..0b01be42deb 100644 --- a/rs/types/types/src/consensus/idkg/common.rs +++ b/rs/types/types/src/consensus/idkg/common.rs @@ -19,6 +19,7 @@ use crate::{Height, RegistryVersion}; use ic_base_types::{NodeId, PrincipalId}; #[cfg(test)] use ic_exhaustive_derive::ExhaustiveSet; +use ic_management_canister_types::MasterPublicKeyId; use ic_protobuf::proxy::{try_from_option_field, ProxyDecodeError}; use ic_protobuf::registry::subnet::v1 as subnet_pb; use ic_protobuf::types::v1 as pb; @@ -1178,3 +1179,13 @@ impl Display for SignatureScheme { } } } + +impl From<&MasterPublicKeyId> for SignatureScheme { + fn from(value: &MasterPublicKeyId) -> Self { + match value { + MasterPublicKeyId::Ecdsa(_) => SignatureScheme::Ecdsa, + MasterPublicKeyId::Schnorr(_) => SignatureScheme::Schnorr, + MasterPublicKeyId::VetKd(_) => SignatureScheme::VetKd, + } + } +} From ba7f1000666b8532319028543ddc45ca37d97630 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 28 Jan 2025 19:59:48 +0000 Subject: [PATCH 04/18] implement replication factor --- rs/interfaces/src/execution_environment/errors.rs | 11 +++++++++++ rs/system_api/src/lib.rs | 9 ++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/rs/interfaces/src/execution_environment/errors.rs b/rs/interfaces/src/execution_environment/errors.rs index 073967a0323..a71006b5a43 100644 --- a/rs/interfaces/src/execution_environment/errors.rs +++ b/rs/interfaces/src/execution_environment/errors.rs @@ -186,6 +186,8 @@ pub enum HypervisorError { bytes: NumBytes, limit: NumBytes, }, + /// A user-specified Principal was not a valid subnet. + SubnetNotFound, } impl From for HypervisorError { @@ -209,6 +211,9 @@ impl From for HypervisorError { impl std::fmt::Display for HypervisorError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + Self::SubnetNotFound => { + write!(f, "User-specified Principal was not a valid subnet.") + } Self::FunctionNotFound(table_idx, func_idx) => write!( f, "Canister requested to invoke a non-existent Wasm function {} from table {}", @@ -401,6 +406,10 @@ impl AsErrorHelp for HypervisorError { Self::FunctionNotFound(_, _) | Self::ToolchainContractViolation { .. } | Self::InvalidPrincipalId(_) => ErrorHelp::ToolchainError, + Self::SubnetNotFound => ErrorHelp::UserError { + suggestion: "Check the provided principal (not a subnet).".to_string(), + doc_link: doc_ref(""), + }, Self::MethodNotFound(_) => ErrorHelp::UserError { suggestion: "Check that the method being called is exported by \ the target canister." @@ -516,6 +525,7 @@ impl HypervisorError { }; let code = match self { + Self::SubnetNotFound => E::SubnetNotFound, Self::FunctionNotFound(_, _) => E::CanisterFunctionNotFound, Self::MethodNotFound(_) => E::CanisterMethodNotFound, Self::ToolchainContractViolation { .. } => E::CanisterContractViolation, @@ -557,6 +567,7 @@ impl HypervisorError { /// e.g. as a metric label. pub fn as_str(&self) -> &'static str { match self { + HypervisorError::SubnetNotFound => "SubnetNotFound", HypervisorError::FunctionNotFound(..) => "FunctionNotFound", HypervisorError::MethodNotFound(_) => "MethodNotFound", HypervisorError::ToolchainContractViolation { .. } => "ToolchainContractViolation", diff --git a/rs/system_api/src/lib.rs b/rs/system_api/src/lib.rs index 6466dfe218e..bcbd1177a81 100644 --- a/rs/system_api/src/lib.rs +++ b/rs/system_api/src/lib.rs @@ -3550,7 +3550,14 @@ impl SystemApi for SystemApiImpl { size: usize, heap: &[u8], ) -> HypervisorResult { - todo!() + let msg_bytes = valid_subslice("ic0_replication_factor", src, size, heap)?; + let subnet_id = PrincipalId::try_from(msg_bytes) + .map_err(|e| HypervisorError::InvalidPrincipalId(PrincipalIdBlobParseError(e.0)))?; + self.sandbox_safe_system_state + .network_topology + .get_subnet_size(&subnet_id.into()) + .map(|x| x as u32) + .ok_or(HypervisorError::SubnetNotFound) } fn ic0_cost_call( From c18d911f3e0675277a70414897386269b2552032 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 28 Jan 2025 20:03:41 +0000 Subject: [PATCH 05/18] implement cost_create_canister --- rs/system_api/src/lib.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/rs/system_api/src/lib.rs b/rs/system_api/src/lib.rs index bcbd1177a81..6921cdf9c9c 100644 --- a/rs/system_api/src/lib.rs +++ b/rs/system_api/src/lib.rs @@ -3571,8 +3571,13 @@ impl SystemApi for SystemApiImpl { } fn ic0_cost_create_canister(&self, dst: usize, heap: &mut [u8]) -> HypervisorResult<()> { - // find own subnet repl factor; get fee, write to dst. - todo!() + let subnet_size = self.sandbox_safe_system_state.subnet_size; + let cost = self + .sandbox_safe_system_state + .cycles_account_manager + .canister_creation_fee(subnet_size); + copy_cycles_to_heap(cost, dst, heap, "ic0_cost_create_canister")?; + Ok(()) } fn ic0_cost_http_request( From 14e84a5c8b8db3049810ae3d1009227406c7eb7f Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 28 Jan 2025 20:11:44 +0000 Subject: [PATCH 06/18] implement cost_call --- rs/system_api/src/lib.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/rs/system_api/src/lib.rs b/rs/system_api/src/lib.rs index 6921cdf9c9c..17d5e95f9bd 100644 --- a/rs/system_api/src/lib.rs +++ b/rs/system_api/src/lib.rs @@ -3567,7 +3567,20 @@ impl SystemApi for SystemApiImpl { dst: usize, heap: &mut [u8], ) -> HypervisorResult<()> { - todo!() + let subnet_size = self.sandbox_safe_system_state.subnet_size; + let cost = self + .sandbox_safe_system_state + .cycles_account_manager + .xnet_call_performed_fee(subnet_size) + + self + .sandbox_safe_system_state + .cycles_account_manager + .xnet_call_bytes_transmitted_fee( + (method_name_size + payload_size).into(), + subnet_size, + ); + copy_cycles_to_heap(cost, dst, heap, "ic0_cost_call")?; + Ok(()) } fn ic0_cost_create_canister(&self, dst: usize, heap: &mut [u8]) -> HypervisorResult<()> { From c4298fb9690796e2fb3902147e7e429b42fd1a33 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Wed, 29 Jan 2025 09:02:27 +0000 Subject: [PATCH 07/18] implement cost_http_request --- rs/system_api/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rs/system_api/src/lib.rs b/rs/system_api/src/lib.rs index 17d5e95f9bd..57003f17f77 100644 --- a/rs/system_api/src/lib.rs +++ b/rs/system_api/src/lib.rs @@ -3600,7 +3600,13 @@ impl SystemApi for SystemApiImpl { dst: usize, heap: &mut [u8], ) -> HypervisorResult<()> { - todo!() + let subnet_size = self.sandbox_safe_system_state.subnet_size; + let cost = self + .sandbox_safe_system_state + .cycles_account_manager + .http_request_fee(request_size.into(), Some(max_res_bytes.into()), subnet_size); + copy_cycles_to_heap(cost, dst, heap, "ic0_cost_http_request")?; + Ok(()) } fn ic0_cost_ecdsa( From ed95b9acdf52b2f4d08d02355a71be4031a659ec Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Wed, 29 Jan 2025 09:18:59 +0000 Subject: [PATCH 08/18] fix ssss --- rs/system_api/src/sandbox_safe_system_state.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rs/system_api/src/sandbox_safe_system_state.rs b/rs/system_api/src/sandbox_safe_system_state.rs index 996df9bbe7f..1a80912c04e 100644 --- a/rs/system_api/src/sandbox_safe_system_state.rs +++ b/rs/system_api/src/sandbox_safe_system_state.rs @@ -1366,7 +1366,9 @@ mod tests { use ic_cycles_account_manager::CyclesAccountManager; use ic_limits::SMALL_APP_SUBNET_MAX_SIZE; use ic_registry_subnet_type::SubnetType; - use ic_replicated_state::{canister_state::system_state::CyclesUseCase, SystemState}; + use ic_replicated_state::{ + canister_state::system_state::CyclesUseCase, NetworkTopology, SystemState, + }; use ic_test_utilities_types::ids::{canister_test_id, subnet_test_id, user_test_id}; use ic_types::{ messages::{RequestMetadata, NO_DEADLINE}, @@ -1479,6 +1481,7 @@ mod tests { 0, // Wasm32 execution environment. Sufficient in testing. false, + NetworkTopology::default(), ); sandbox_state.msg_deadline() } @@ -1529,6 +1532,7 @@ mod tests { 0, // Wasm32 execution environment. Sufficient in testing. false, + NetworkTopology::default(), ) } From 8613b76b26c3daf2923c2b0f6822a9330c0e5b50 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Wed, 29 Jan 2025 09:33:17 +0000 Subject: [PATCH 09/18] clippy --- rs/replicated_state/src/metadata_state.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/rs/replicated_state/src/metadata_state.rs b/rs/replicated_state/src/metadata_state.rs index 36ba46482e1..1e1543e1878 100644 --- a/rs/replicated_state/src/metadata_state.rs +++ b/rs/replicated_state/src/metadata_state.rs @@ -251,12 +251,9 @@ impl NetworkTopology { signature_scheme: SignatureScheme, key_name: &str, ) -> Option<&MasterPublicKeyId> { - for entry in self.chain_key_enabled_subnets.keys() { - if signature_scheme == entry.into() && key_name == entry.get_key_name() { - return Some(entry); - } - } - None + self.chain_key_enabled_subnets + .keys() + .find(|&entry| signature_scheme == entry.into() && key_name == entry.get_key_name()) } } From b50c8198ea2b23e5bd11513b15ef5f869196329c Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Wed, 29 Jan 2025 09:45:07 +0000 Subject: [PATCH 10/18] clippy --- rs/canister_sandbox/src/sandbox_server.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rs/canister_sandbox/src/sandbox_server.rs b/rs/canister_sandbox/src/sandbox_server.rs index 9ac46749ccc..89e4faca93f 100644 --- a/rs/canister_sandbox/src/sandbox_server.rs +++ b/rs/canister_sandbox/src/sandbox_server.rs @@ -162,7 +162,7 @@ mod tests { use ic_limits::SMALL_APP_SUBNET_MAX_SIZE; use ic_logger::replica_logger::no_op_logger; use ic_registry_subnet_type::SubnetType; - use ic_replicated_state::{Global, NumWasmPages, PageIndex, PageMap}; + use ic_replicated_state::{Global, NetworkTopology, NumWasmPages, PageIndex, PageMap}; use ic_system_api::{ sandbox_safe_system_state::{CanisterStatusView, SandboxSafeSystemState}, ApiType, ExecutionParameters, InstructionLimits, @@ -242,6 +242,7 @@ mod tests { caller, 0, IS_WASM64_EXECUTION, + NetworkTopology::default(), ) } From a69255b86f4ef5feec2d3d35e374886f9d5cfd2d Mon Sep 17 00:00:00 2001 From: michael-weigelt <122277901+michael-weigelt@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:24:12 +0100 Subject: [PATCH 11/18] Update rs/interfaces/src/execution_environment.rs Co-authored-by: Leo Eichhorn <99166915+eichhorl@users.noreply.github.com> --- rs/interfaces/src/execution_environment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/interfaces/src/execution_environment.rs b/rs/interfaces/src/execution_environment.rs index 3f2afe6f6e9..906f8ee9a43 100644 --- a/rs/interfaces/src/execution_environment.rs +++ b/rs/interfaces/src/execution_environment.rs @@ -1254,7 +1254,7 @@ pub trait SystemApi { ) -> HypervisorResult<()>; /// This system call indicates the cycle cost of signing with ecdsa, - /// i.e., the management canister's `vetkd_encrypted_key` for the key + /// i.e., the management canister's `vetkd_derive_encrypted_key` for the key /// with name given by `src` + `size`. /// /// Traps if `src`/`size` cannot be decoded to a valid key name. From fcc7e41c39d4cd92f527c40929997741a10cea3d Mon Sep 17 00:00:00 2001 From: michael-weigelt <122277901+michael-weigelt@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:24:20 +0100 Subject: [PATCH 12/18] Update rs/interfaces/src/execution_environment.rs Co-authored-by: Leo Eichhorn <99166915+eichhorl@users.noreply.github.com> --- rs/interfaces/src/execution_environment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/interfaces/src/execution_environment.rs b/rs/interfaces/src/execution_environment.rs index 906f8ee9a43..420882a27a7 100644 --- a/rs/interfaces/src/execution_environment.rs +++ b/rs/interfaces/src/execution_environment.rs @@ -1253,7 +1253,7 @@ pub trait SystemApi { heap: &mut [u8], ) -> HypervisorResult<()>; - /// This system call indicates the cycle cost of signing with ecdsa, + /// This system call indicates the cycle cost of threshold key derivation, /// i.e., the management canister's `vetkd_derive_encrypted_key` for the key /// with name given by `src` + `size`. /// From 1ff90d2048275630aab12bbb12edd065762c73e5 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 4 Feb 2025 09:42:09 +0000 Subject: [PATCH 13/18] use full keyid for lookup --- rs/interfaces/src/execution_environment.rs | 17 +-- rs/replicated_state/src/metadata_state.rs | 11 -- rs/system_api/src/lib.rs | 128 +++++++++++---------- 3 files changed, 78 insertions(+), 78 deletions(-) diff --git a/rs/interfaces/src/execution_environment.rs b/rs/interfaces/src/execution_environment.rs index 420882a27a7..b3c37b65353 100644 --- a/rs/interfaces/src/execution_environment.rs +++ b/rs/interfaces/src/execution_environment.rs @@ -4,7 +4,7 @@ mod errors; pub use errors::{CanisterBacktrace, CanisterOutOfCyclesError, HypervisorError, TrapCode}; use ic_base_types::NumBytes; use ic_error_types::UserError; -use ic_management_canister_types::MasterPublicKeyId; +use ic_management_canister_types::{EcdsaCurve, MasterPublicKeyId, SchnorrAlgorithm, VetKdCurve}; use ic_registry_provisional_whitelist::ProvisionalWhitelist; use ic_registry_subnet_type::SubnetType; use ic_sys::{PageBytes, PageIndex}; @@ -1223,48 +1223,51 @@ pub trait SystemApi { /// This system call indicates the cycle cost of signing with ecdsa, /// i.e., the management canister's `sign_with_ecdsa`, for the key - /// with name given by `src` + `size`. + /// with name given by `src` + `size` and the provided curve. /// /// Traps if `src`/`size` cannot be decoded to a valid key name. /// /// The amount of cycles is represented by a 128-bit value and is copied /// to the canister memory starting at the location `dst`. - fn ic0_cost_ecdsa( + fn ic0_cost_sign_with_ecdsa( &self, src: usize, size: usize, + curve: EcdsaCurve, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()>; /// This system call indicates the cycle cost of signing with schnorr, /// i.e., the management canister's `sign_with_schnorr` for the key - /// with name given by `src` + `size`. + /// with name given by `src` + `size` and the provided algorithm. /// /// Traps if `src`/`size` cannot be decoded to a valid key name. /// /// The amount of cycles is represented by a 128-bit value and is copied /// to the canister memory starting at the location `dst`. - fn ic0_cost_schnorr( + fn ic0_cost_sign_with_schnorr( &self, src: usize, size: usize, + algorithm: SchnorrAlgorithm, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()>; /// This system call indicates the cycle cost of threshold key derivation, /// i.e., the management canister's `vetkd_derive_encrypted_key` for the key - /// with name given by `src` + `size`. + /// with name given by `src` + `size` and the provided curve. /// /// Traps if `src`/`size` cannot be decoded to a valid key name. /// /// The amount of cycles is represented by a 128-bit value and is copied /// to the canister memory starting at the location `dst`. - fn ic0_cost_vetkey( + fn ic0_cost_vetkd_derive_encrypted_key( &self, src: usize, size: usize, + curve: VetKdCurve, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()>; diff --git a/rs/replicated_state/src/metadata_state.rs b/rs/replicated_state/src/metadata_state.rs index 1e1543e1878..b77aa920c7f 100644 --- a/rs/replicated_state/src/metadata_state.rs +++ b/rs/replicated_state/src/metadata_state.rs @@ -29,7 +29,6 @@ use ic_registry_routing_table::{ }; use ic_registry_subnet_features::SubnetFeatures; use ic_registry_subnet_type::SubnetType; -use ic_types::consensus::idkg::common::SignatureScheme; use ic_types::{ batch::BlockmakerMetrics, crypto::CryptoHash, @@ -245,16 +244,6 @@ impl NetworkTopology { .get(subnet_id) .map(|subnet_topology| subnet_topology.nodes.len()) } - - pub fn get_key_by_name( - &self, - signature_scheme: SignatureScheme, - key_name: &str, - ) -> Option<&MasterPublicKeyId> { - self.chain_key_enabled_subnets - .keys() - .find(|&entry| signature_scheme == entry.into() && key_name == entry.get_key_name()) - } } impl From<&NetworkTopology> for pb_metadata::NetworkTopology { diff --git a/rs/system_api/src/lib.rs b/rs/system_api/src/lib.rs index 57003f17f77..2ae62f62629 100644 --- a/rs/system_api/src/lib.rs +++ b/rs/system_api/src/lib.rs @@ -11,6 +11,10 @@ use ic_interfaces::execution_environment::{ TrapCode::{self, CyclesAmountTooBigFor64Bit}, }; use ic_logger::{error, ReplicaLogger}; +use ic_management_canister_types::{ + EcdsaCurve, EcdsaKeyId, MasterPublicKeyId, SchnorrAlgorithm, SchnorrKeyId, VetKdCurve, + VetKdKeyId, +}; use ic_registry_subnet_type::SubnetType; use ic_replicated_state::{ canister_state::WASM_PAGE_SIZE_IN_BYTES, memory_required_to_push_request, Memory, @@ -18,7 +22,6 @@ use ic_replicated_state::{ }; use ic_sys::PageBytes; use ic_types::{ - consensus::idkg::common::SignatureScheme, ingress::WasmResult, messages::{CallContextId, RejectContext, Request, MAX_INTER_CANISTER_PAYLOAD_IN_BYTES}, methods::{SystemMethod, WasmClosure}, @@ -3553,11 +3556,14 @@ impl SystemApi for SystemApiImpl { let msg_bytes = valid_subslice("ic0_replication_factor", src, size, heap)?; let subnet_id = PrincipalId::try_from(msg_bytes) .map_err(|e| HypervisorError::InvalidPrincipalId(PrincipalIdBlobParseError(e.0)))?; - self.sandbox_safe_system_state + let result = self + .sandbox_safe_system_state .network_topology .get_subnet_size(&subnet_id.into()) .map(|x| x as u32) - .ok_or(HypervisorError::SubnetNotFound) + .ok_or(HypervisorError::SubnetNotFound); + trace_syscall!(self, ReplicationFactor, result); + result } fn ic0_cost_call( @@ -3580,6 +3586,7 @@ impl SystemApi for SystemApiImpl { subnet_size, ); copy_cycles_to_heap(cost, dst, heap, "ic0_cost_call")?; + trace_syscall!(self, CostCall, cost); Ok(()) } @@ -3590,6 +3597,7 @@ impl SystemApi for SystemApiImpl { .cycles_account_manager .canister_creation_fee(subnet_size); copy_cycles_to_heap(cost, dst, heap, "ic0_cost_create_canister")?; + trace_syscall!(self, CostCreateCanister, cost); Ok(()) } @@ -3606,115 +3614,115 @@ impl SystemApi for SystemApiImpl { .cycles_account_manager .http_request_fee(request_size.into(), Some(max_res_bytes.into()), subnet_size); copy_cycles_to_heap(cost, dst, heap, "ic0_cost_http_request")?; + trace_syscall!(self, CostHttpRequest, cost); Ok(()) } - fn ic0_cost_ecdsa( + fn ic0_cost_sign_with_ecdsa( &self, src: usize, size: usize, + curve: EcdsaCurve, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()> { + let key_bytes = valid_subslice("ic0.cost_sign_with_ecdsa heap", src, size, heap)?; + let name = str::from_utf8(key_bytes) + .map_err(|_| HypervisorError::ToolchainContractViolation { + error: format!( + "Failed to decode key name {}", + String::from_utf8_lossy(key_bytes) + ), + })? + .to_string(); + let key = MasterPublicKeyId::Ecdsa(EcdsaKeyId { curve, name }); let topology = &self.sandbox_safe_system_state.network_topology; - let subnet_size = get_signing_key_replication_factor( - SignatureScheme::Ecdsa, - "ecdsa", - topology, - src, - size, - heap, - )?; + let subnet_size = get_key_replication_factor(topology, key)?; let cost = self .sandbox_safe_system_state .cycles_account_manager .ecdsa_signature_fee(subnet_size); - copy_cycles_to_heap(cost, dst, heap, "ic0_cost_ecdsa")?; + copy_cycles_to_heap(cost, dst, heap, "ic0_cost_sign_with_ecdsa")?; + trace_syscall!(self, CostSignWithEcdsa, cost); Ok(()) } - fn ic0_cost_schnorr( + fn ic0_cost_sign_with_schnorr( &self, src: usize, size: usize, + algorithm: SchnorrAlgorithm, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()> { + let key_bytes = valid_subslice("ic0.cost_sign_with_schnorr heap", src, size, heap)?; + let name = str::from_utf8(key_bytes) + .map_err(|_| HypervisorError::ToolchainContractViolation { + error: format!( + "Failed to decode key name {}", + String::from_utf8_lossy(key_bytes) + ), + })? + .to_string(); + let key = MasterPublicKeyId::Schnorr(SchnorrKeyId { algorithm, name }); let topology = &self.sandbox_safe_system_state.network_topology; - let subnet_size = get_signing_key_replication_factor( - SignatureScheme::Schnorr, - "schnorr", - topology, - src, - size, - heap, - )?; + let subnet_size = get_key_replication_factor(topology, key)?; let cost = self .sandbox_safe_system_state .cycles_account_manager .schnorr_signature_fee(subnet_size); - copy_cycles_to_heap(cost, dst, heap, "ic0_cost_schnorr")?; + copy_cycles_to_heap(cost, dst, heap, "ic0_cost_sign_with_schnorr")?; + trace_syscall!(self, CostSignWithSchnorr, cost); Ok(()) } - fn ic0_cost_vetkey( + fn ic0_cost_vetkd_derive_encrypted_key( &self, src: usize, size: usize, + curve: VetKdCurve, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()> { + let key_bytes = + valid_subslice("ic0.cost_vetkd_derive_encrypted_key heap", src, size, heap)?; + let name = str::from_utf8(key_bytes) + .map_err(|_| HypervisorError::ToolchainContractViolation { + error: format!( + "Failed to decode key name {}", + String::from_utf8_lossy(key_bytes) + ), + })? + .to_string(); + let key = MasterPublicKeyId::VetKd(VetKdKeyId { curve, name }); let topology = &self.sandbox_safe_system_state.network_topology; - let subnet_size = get_signing_key_replication_factor( - SignatureScheme::VetKd, - "vetkey", - topology, - src, - size, - heap, - )?; + let subnet_size = get_key_replication_factor(topology, key)?; let cost = self .sandbox_safe_system_state .cycles_account_manager .vetkd_fee(subnet_size); - copy_cycles_to_heap(cost, dst, heap, "ic0_cost_vetkey")?; + copy_cycles_to_heap(cost, dst, heap, "ic0_cost_vetkd_derive_encrypted_key")?; + trace_syscall!(self, CostVetkdDeriveEncryptedKey, cost); Ok(()) } } -/// Common steps for the syscalls `ic0_cost_ecdsa`, `ic0_cost_schnorr` and `ic0_cost_vetkey`. -/// Extract the key name, look it up in `chain_key_enabled_subnets`, then extract all subnets +/// Look up key in `chain_key_enabled_subnets`, then extract all subnets /// for that key and return the replication factor of the biggest one. -fn get_signing_key_replication_factor( - scheme: SignatureScheme, - scheme_str: &str, +fn get_key_replication_factor( topology: &NetworkTopology, - src: usize, - size: usize, - heap: &mut [u8], + key: MasterPublicKeyId, ) -> HypervisorResult { - let key_bytes = valid_subslice(&format!("ic0.cost_{} heap", scheme_str), src, size, heap)?; - let key_name = - str::from_utf8(key_bytes).map_err(|_| HypervisorError::ToolchainContractViolation { - error: format!( - "Failed to decode key name {}", - String::from_utf8_lossy(key_bytes) - ), - })?; - let key_id = topology.get_key_by_name(scheme, key_name).ok_or( - HypervisorError::ToolchainContractViolation { - error: format!("{} signing key {} not known.", scheme, key_name), - }, - )?; - let max_subnet_size = topology - .chain_key_enabled_subnets(key_id) - .iter() // this is non-empty, otherwise key_id would have errored + let subnets_with_key = topology.chain_key_enabled_subnets(&key); + subnets_with_key + .iter() .map(|subnet_id| { - topology.get_subnet_size(subnet_id).unwrap() // we got the subnet_id from the collection + topology.get_subnet_size(subnet_id).unwrap() // we got the subnet_id from the same collection }) .max() - .unwrap(); // the maximum of a non-empty sequence of usize exists - Ok(max_subnet_size) + .ok_or(HypervisorError::ToolchainContractViolation { + error: format!("Public key {:?} not known.", key), + }) } /// The default implementation of the `OutOfInstructionHandler` trait. From e3f6a0a88769bd9703b04ab44570421fd0f4ab4e Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 4 Feb 2025 10:41:03 +0000 Subject: [PATCH 14/18] tryinto curves --- rs/types/management_canister_types/src/lib.rs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/rs/types/management_canister_types/src/lib.rs b/rs/types/management_canister_types/src/lib.rs index 88580a7ee29..17ff8fcef80 100644 --- a/rs/types/management_canister_types/src/lib.rs +++ b/rs/types/management_canister_types/src/lib.rs @@ -2010,6 +2010,19 @@ pub enum EcdsaCurve { Secp256k1, } +impl TryFrom for EcdsaCurve { + type Error = String; + + fn try_from(value: u32) -> Result { + match value { + 0 => Ok(EcdsaCurve::Secp256k1), + _ => Err(format!( + "{value} is not a recognized EcdsaCurve variant identifier." + )), + } + } +} + impl From<&EcdsaCurve> for pb_types::EcdsaCurve { fn from(item: &EcdsaCurve) -> Self { match item { @@ -2131,6 +2144,20 @@ pub enum SchnorrAlgorithm { Ed25519, } +impl TryFrom for SchnorrAlgorithm { + type Error = String; + + fn try_from(value: u32) -> Result { + match value { + 0 => Ok(SchnorrAlgorithm::Bip340Secp256k1), + 1 => Ok(SchnorrAlgorithm::Ed25519), + _ => Err(format!( + "{value} is not a recognized SchnorrAlgorithm variant identifier." + )), + } + } +} + impl From<&SchnorrAlgorithm> for pb_types::SchnorrAlgorithm { fn from(item: &SchnorrAlgorithm) -> Self { match item { @@ -2254,6 +2281,19 @@ pub enum VetKdCurve { Bls12_381_G2, } +impl TryFrom for VetKdCurve { + type Error = String; + + fn try_from(value: u32) -> Result { + match value { + 0 => Ok(VetKdCurve::Bls12_381_G2), + _ => Err(format!( + "{value} is not a recognized VetKdCurve variant identifier." + )), + } + } +} + impl From<&VetKdCurve> for pb_types::VetKdCurve { fn from(item: &VetKdCurve) -> Self { match item { From 47e7ad51a0d093271884d8c38c3bf667eeccc1ec Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 4 Feb 2025 10:50:58 +0000 Subject: [PATCH 15/18] conversion in system_api, not embedders --- rs/interfaces/src/execution_environment.rs | 8 ++++---- rs/system_api/src/lib.rs | 12 +++++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/rs/interfaces/src/execution_environment.rs b/rs/interfaces/src/execution_environment.rs index c05db4dba44..b5675bac661 100644 --- a/rs/interfaces/src/execution_environment.rs +++ b/rs/interfaces/src/execution_environment.rs @@ -4,7 +4,7 @@ mod errors; pub use errors::{CanisterBacktrace, CanisterOutOfCyclesError, HypervisorError, TrapCode}; use ic_base_types::NumBytes; use ic_error_types::UserError; -use ic_management_canister_types::{EcdsaCurve, MasterPublicKeyId, SchnorrAlgorithm, VetKdCurve}; +use ic_management_canister_types::MasterPublicKeyId; use ic_registry_provisional_whitelist::ProvisionalWhitelist; use ic_registry_subnet_type::SubnetType; use ic_sys::{PageBytes, PageIndex}; @@ -1237,7 +1237,7 @@ pub trait SystemApi { &self, src: usize, size: usize, - curve: EcdsaCurve, + curve: u32, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()>; @@ -1254,7 +1254,7 @@ pub trait SystemApi { &self, src: usize, size: usize, - algorithm: SchnorrAlgorithm, + algorithm: u32, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()>; @@ -1271,7 +1271,7 @@ pub trait SystemApi { &self, src: usize, size: usize, - curve: VetKdCurve, + curve: u32, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()>; diff --git a/rs/system_api/src/lib.rs b/rs/system_api/src/lib.rs index 8f819f6131e..65e426082bf 100644 --- a/rs/system_api/src/lib.rs +++ b/rs/system_api/src/lib.rs @@ -3592,7 +3592,7 @@ impl SystemApi for SystemApiImpl { &self, src: usize, size: usize, - curve: EcdsaCurve, + curve: u32, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()> { @@ -3605,6 +3605,8 @@ impl SystemApi for SystemApiImpl { ), })? .to_string(); + let curve = EcdsaCurve::try_from(curve) + .map_err(|e| HypervisorError::ToolchainContractViolation { error: e })?; let key = MasterPublicKeyId::Ecdsa(EcdsaKeyId { curve, name }); let topology = &self.sandbox_safe_system_state.network_topology; let subnet_size = get_key_replication_factor(topology, key)?; @@ -3621,7 +3623,7 @@ impl SystemApi for SystemApiImpl { &self, src: usize, size: usize, - algorithm: SchnorrAlgorithm, + algorithm: u32, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()> { @@ -3634,6 +3636,8 @@ impl SystemApi for SystemApiImpl { ), })? .to_string(); + let algorithm = SchnorrAlgorithm::try_from(algorithm) + .map_err(|e| HypervisorError::ToolchainContractViolation { error: e })?; let key = MasterPublicKeyId::Schnorr(SchnorrKeyId { algorithm, name }); let topology = &self.sandbox_safe_system_state.network_topology; let subnet_size = get_key_replication_factor(topology, key)?; @@ -3650,7 +3654,7 @@ impl SystemApi for SystemApiImpl { &self, src: usize, size: usize, - curve: VetKdCurve, + curve: u32, dst: usize, heap: &mut [u8], ) -> HypervisorResult<()> { @@ -3664,6 +3668,8 @@ impl SystemApi for SystemApiImpl { ), })? .to_string(); + let curve = VetKdCurve::try_from(curve) + .map_err(|e| HypervisorError::ToolchainContractViolation { error: e })?; let key = MasterPublicKeyId::VetKd(VetKdKeyId { curve, name }); let topology = &self.sandbox_safe_system_state.network_topology; let subnet_size = get_key_replication_factor(topology, key)?; From 81b8b700bdba38ba8e71b7d197a66ef0156c01a4 Mon Sep 17 00:00:00 2001 From: michael-weigelt <122277901+michael-weigelt@users.noreply.github.com> Date: Tue, 4 Feb 2025 11:52:06 +0100 Subject: [PATCH 16/18] Update rs/types/management_canister_types/src/lib.rs Co-authored-by: Leo Eichhorn <99166915+eichhorl@users.noreply.github.com> --- rs/types/management_canister_types/src/lib.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/rs/types/management_canister_types/src/lib.rs b/rs/types/management_canister_types/src/lib.rs index 17ff8fcef80..a8c9acccc22 100644 --- a/rs/types/management_canister_types/src/lib.rs +++ b/rs/types/management_canister_types/src/lib.rs @@ -2474,14 +2474,6 @@ impl MasterPublicKeyId { Self::VetKd(_) => false, } } - - pub fn get_key_name(&self) -> &str { - match self { - MasterPublicKeyId::Ecdsa(EcdsaKeyId { name, .. }) => name, - MasterPublicKeyId::Schnorr(SchnorrKeyId { name, .. }) => name, - MasterPublicKeyId::VetKd(VetKdKeyId { name, .. }) => name, - } - } } impl FromStr for MasterPublicKeyId { From 0b9a95e60f37f8f82e759cfa24d1817cce5e0073 Mon Sep 17 00:00:00 2001 From: michael-weigelt <122277901+michael-weigelt@users.noreply.github.com> Date: Tue, 4 Feb 2025 11:52:17 +0100 Subject: [PATCH 17/18] Update rs/types/types/src/consensus/idkg/common.rs Co-authored-by: Leo Eichhorn <99166915+eichhorl@users.noreply.github.com> --- rs/types/types/src/consensus/idkg/common.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/rs/types/types/src/consensus/idkg/common.rs b/rs/types/types/src/consensus/idkg/common.rs index 0b01be42deb..f288b3ab7f4 100644 --- a/rs/types/types/src/consensus/idkg/common.rs +++ b/rs/types/types/src/consensus/idkg/common.rs @@ -1179,13 +1179,3 @@ impl Display for SignatureScheme { } } } - -impl From<&MasterPublicKeyId> for SignatureScheme { - fn from(value: &MasterPublicKeyId) -> Self { - match value { - MasterPublicKeyId::Ecdsa(_) => SignatureScheme::Ecdsa, - MasterPublicKeyId::Schnorr(_) => SignatureScheme::Schnorr, - MasterPublicKeyId::VetKd(_) => SignatureScheme::VetKd, - } - } -} From f9b5f5c357954deea97445cf18df496613eb46d5 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Tue, 4 Feb 2025 10:54:57 +0000 Subject: [PATCH 18/18] import --- rs/types/types/src/consensus/idkg/common.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/rs/types/types/src/consensus/idkg/common.rs b/rs/types/types/src/consensus/idkg/common.rs index f288b3ab7f4..9409a4b0fa4 100644 --- a/rs/types/types/src/consensus/idkg/common.rs +++ b/rs/types/types/src/consensus/idkg/common.rs @@ -19,7 +19,6 @@ use crate::{Height, RegistryVersion}; use ic_base_types::{NodeId, PrincipalId}; #[cfg(test)] use ic_exhaustive_derive::ExhaustiveSet; -use ic_management_canister_types::MasterPublicKeyId; use ic_protobuf::proxy::{try_from_option_field, ProxyDecodeError}; use ic_protobuf::registry::subnet::v1 as subnet_pb; use ic_protobuf::types::v1 as pb;