diff --git a/runtime-sdk/src/modules/core/mod.rs b/runtime-sdk/src/modules/core/mod.rs index c366c66872..65ecca7918 100644 --- a/runtime-sdk/src/modules/core/mod.rs +++ b/runtime-sdk/src/modules/core/mod.rs @@ -427,6 +427,8 @@ pub trait Config: 'static { const GAS_COST_CALL_CALLDATA_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 +848,25 @@ 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 epoch = ctx.epoch(); + let key_pair_id = callformat::get_key_pair_id(epoch); + let public_key = key_manager + .get_public_key(key_pair_id) + .map_err(|_| Error::InvalidArgument(anyhow!("cannot get public key")))?; + let runtime_id = *ctx.runtime_id(); + Ok(types::KeyManagerPublicKeyQueryResponse { + runtime_id, + key_pair_id, + public_key, + }) + } + fn calldata_public_key_common( ctx: &C, ) -> Result { @@ -865,6 +886,25 @@ impl Module { Ok(types::CallDataPublicKeyQueryResponse { public_key, epoch }) } + /// 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_CALLDATA_PUBLIC_KEY)?; + Self::keymanager_public_key_common(ctx) + } + /// Retrieve the public key for encrypting call data. #[handler(query = "core.CallDataPublicKey")] fn query_calldata_public_key( diff --git a/runtime-sdk/src/modules/core/test.rs b/runtime-sdk/src/modules/core/test.rs index 2b1be1bcfe..9111b24701 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 13d5f10263..a2f05bb383 100644 --- a/runtime-sdk/src/modules/core/types.rs +++ b/runtime-sdk/src/modules/core/types.rs @@ -1,10 +1,13 @@ use std::collections::BTreeMap; use crate::{ + core::common::namespace::Namespace, keymanager::SignedPublicKey, types::transaction::{CallResult, CallerAddress, Transaction}, }; +use oasis_core_keymanager::crypto::KeyPairId; + /// Key in the versions map used for the global state version. pub const VERSION_GLOBAL_KEY: &str = ""; @@ -41,6 +44,17 @@ pub struct CallDataPublicKeyQueryResponse { pub epoch: u64, } +/// Response to the public key query. +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] +pub struct KeyManagerPublicKeyQueryResponse { + /// ID of the public key which signs the call data public keys + pub key_pair_id: KeyPairId, + /// Public key which signs the call data public keys + pub public_key: SignedPublicKey, + /// For reference, which runtime ID is this for? + pub runtime_id: Namespace, +} + #[derive(Debug, Copy, Clone, cbor::Encode, cbor::Decode)] #[cfg_attr(test, derive(PartialEq, Eq))] pub enum MethodHandlerKind {