From 50658ab2990383e20c70068964115143ab729468 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Fri, 25 Oct 2024 09:58:46 +0200 Subject: [PATCH] runtime-sdk/src/modules/core: add "core.KeyManagerPublicKey" --- runtime-sdk/src/modules/core/mod.rs | 42 +++++++++++++++++++++++++-- runtime-sdk/src/modules/core/test.rs | 2 ++ runtime-sdk/src/modules/core/types.rs | 15 ++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/runtime-sdk/src/modules/core/mod.rs b/runtime-sdk/src/modules/core/mod.rs index c366c668725..a9f0ba60470 100644 --- a/runtime-sdk/src/modules/core/mod.rs +++ b/runtime-sdk/src/modules/core/mod.rs @@ -33,6 +33,8 @@ use crate::{ Runtime, }; +use oasis_core_runtime::common::crypto::signature::PublicKey; + use self::types::RuntimeInfoResponse; #[cfg(test)] @@ -425,8 +427,12 @@ pub trait Config: 'static { /// The gas cost of the internal call to retrieve the current calldata public key. const GAS_COST_CALL_CALLDATA_PUBLIC_KEY: u64 = 20; + /// The gas cost of the internal call to retrieve the current key managers runtime signing public key. + const GAS_COST_CALL_KEYMANAGER_PUBLIC_KEY: u64 = 20; /// The gas cost of the internal call to retrieve the current epoch. const GAS_COST_CALL_CURRENT_EPOCH: u64 = 10; + /// The gas cost of the internal call to retrieve the current long-term public key + const GAS_COST_CALL_PUBLIC_KEY: u64 = 20; } pub struct Module { @@ -846,6 +852,17 @@ impl Module { ::Modules::check_invariants(ctx) } + fn keymanager_public_key_common(ctx: &C) -> Result { + let key_manager = ctx + .key_manager() + .ok_or_else(|| Error::InvalidArgument(anyhow!("key manager not available")))?; + let public_key = key_manager + .runtime_signing_key() + .ok_or_else(|| Error::InvalidArgument(anyhow!("cannot get runtime signing key")))?; + + Ok(public_key) + } + fn calldata_public_key_common( ctx: &C, ) -> Result { @@ -853,8 +870,9 @@ impl Module { .key_manager() .ok_or_else(|| Error::InvalidArgument(anyhow!("key manager not available")))?; let epoch = ctx.epoch(); + let key_pair_id = callformat::get_key_pair_id(epoch); let public_key = key_manager - .get_public_ephemeral_key(callformat::get_key_pair_id(epoch), epoch) + .get_public_ephemeral_key(key_pair_id, epoch) .map_err(|err| match err { keymanager::KeyManagerError::InvalidEpoch(..) => { Error::InvalidCallFormat(anyhow!("invalid epoch")) @@ -862,7 +880,27 @@ impl Module { _ => Error::Abort(err.into()), })?; - Ok(types::CallDataPublicKeyQueryResponse { public_key, epoch }) + let runtime_id = *ctx.runtime_id(); + + Ok(types::CallDataPublicKeyQueryResponse { + public_key, + epoch, + runtime_id, + key_pair_id, + }) + } + + /// Retrieve the public key for encrypting call data. + #[handler(query = "core.KeyManagerPublicKey")] + fn query_keymanager_public_key(ctx: &C, _args: ()) -> Result { + Self::keymanager_public_key_common(ctx) + } + + /// Retrieve the public key for encrypting call data (internally exposed call). + #[handler(call = "core.KeyManagerPublicKey", internal)] + fn internal_keymanager_public_key(ctx: &C, _args: ()) -> Result { + ::Core::use_tx_gas(Cfg::GAS_COST_CALL_KEYMANAGER_PUBLIC_KEY)?; + Self::keymanager_public_key_common(ctx) } /// Retrieve the public key for encrypting call data. diff --git a/runtime-sdk/src/modules/core/test.rs b/runtime-sdk/src/modules/core/test.rs index 2b1be1bcfe1..9111b24701a 100644 --- a/runtime-sdk/src/modules/core/test.rs +++ b/runtime-sdk/src/modules/core/test.rs @@ -1174,6 +1174,8 @@ fn test_module_info() { methods: vec![ MethodHandlerInfo { kind: MethodHandlerKind::Query, name: "core.EstimateGas".to_string() }, MethodHandlerInfo { kind: MethodHandlerKind::Query, name: "core.CheckInvariants".to_string() }, + MethodHandlerInfo { kind: MethodHandlerKind::Query, name: "core.KeyManagerPublicKey".to_string() }, + MethodHandlerInfo { kind: MethodHandlerKind::Call, name: "core.KeyManagerPublicKey".to_string() }, MethodHandlerInfo { kind: MethodHandlerKind::Query, name: "core.CallDataPublicKey".to_string() }, MethodHandlerInfo { kind: MethodHandlerKind::Call, name: "core.CallDataPublicKey".to_string() }, MethodHandlerInfo { kind: MethodHandlerKind::Call, name: "core.CurrentEpoch".to_string() }, diff --git a/runtime-sdk/src/modules/core/types.rs b/runtime-sdk/src/modules/core/types.rs index 13d5f10263d..cc8d485936e 100644 --- a/runtime-sdk/src/modules/core/types.rs +++ b/runtime-sdk/src/modules/core/types.rs @@ -1,10 +1,14 @@ use std::collections::BTreeMap; use crate::{ + core::common::namespace::Namespace, keymanager::SignedPublicKey, types::transaction::{CallResult, CallerAddress, Transaction}, }; +use oasis_core_keymanager::crypto::KeyPairId; +use oasis_core_runtime::common::crypto::signature::PublicKey; + /// Key in the versions map used for the global state version. pub const VERSION_GLOBAL_KEY: &str = ""; @@ -39,6 +43,17 @@ pub struct CallDataPublicKeyQueryResponse { pub public_key: SignedPublicKey, /// Epoch of the ephemeral runtime key. pub epoch: u64, + /// Runtime ID the ephemeral SignedPublicKey belongs to + pub runtime_id: Namespace, + /// ID of the public key which signs the call data public keys + pub key_pair_id: KeyPairId, +} + +/// Response to the public key query. +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] +pub struct KeyManagerPublicKeyQueryResponse { + /// Runtime signing key which signs the call data public keys + pub public_key: PublicKey, } #[derive(Debug, Copy, Clone, cbor::Encode, cbor::Decode)]