holochain_conductor_services/
dpki_service.rsuse std::sync::Arc;
pub use hc_deepkey_sdk::*;
use holochain_types::prelude::*;
use holochain_util::timed;
pub mod derivation_paths;
mod deepkey;
pub use deepkey::*;
use crate::CellRunner;
pub const DPKI_APP_ID: &str = "DPKI";
pub type DpkiImpl = Arc<DpkiService>;
pub struct DpkiService {
pub cell_id: CellId,
state: tokio::sync::Mutex<Box<dyn DpkiState>>,
}
impl DpkiService {
pub fn new(cell_id: CellId, state: impl DpkiState + 'static) -> Self {
let state: Box<dyn DpkiState> = Box::new(state);
let state = tokio::sync::Mutex::new(state);
Self { cell_id, state }
}
pub fn is_deepkey_dna(&self, dna_hash: &DnaHash) -> bool {
self.cell_id.dna_hash() == dna_hash
}
pub fn uuid(&self) -> [u8; 32] {
self.cell_id.dna_hash().get_raw_32().try_into().unwrap()
}
pub fn new_deepkey(installation: DeepkeyInstallation, runner: Arc<impl CellRunner>) -> Self {
let state: Box<dyn DpkiState> = Box::new(DeepkeyState {
runner,
cell_id: installation.cell_id.clone(),
});
let cell_id = installation.cell_id;
let state = tokio::sync::Mutex::new(state);
Self { cell_id, state }
}
pub async fn state(&self) -> tokio::sync::MutexGuard<Box<dyn DpkiState>> {
timed!([1, 10, 1000], { self.state.lock().await })
}
}
#[async_trait::async_trait]
#[mockall::automock]
pub trait DpkiState: Send + Sync {
async fn next_derivation_details(
&self,
agent_key: AgentPubKey,
) -> DpkiServiceResult<DerivationDetails>;
async fn register_key(
&self,
input: CreateKeyInput,
) -> DpkiServiceResult<(ActionHash, KeyRegistration, KeyMeta)>;
async fn query_key_meta(&self, key: AgentPubKey) -> DpkiServiceResult<KeyMeta>;
async fn revoke_key(
&self,
input: RevokeKeyInput,
) -> DpkiServiceResult<(ActionHash, KeyRegistration)>;
async fn key_state(
&self,
key: AgentPubKey,
timestamp: Timestamp,
) -> DpkiServiceResult<KeyState>;
async fn get_agent_key_lineage(&self, key: AgentPubKey) -> DpkiServiceResult<Vec<AgentPubKey>>;
async fn is_same_agent(
&self,
key_1: AgentPubKey,
key_2: AgentPubKey,
) -> DpkiServiceResult<bool>;
}
#[derive(thiserror::Error, Debug)]
#[allow(missing_docs)]
pub enum DpkiServiceError {
#[error("DPKI DNA call failed: {0}")]
ZomeCallFailed(anyhow::Error),
#[error(transparent)]
Serialization(#[from] SerializedBytesError),
#[error("Error talking to lair keystore: {0}")]
Lair(anyhow::Error),
#[error("DPKI service not installed")]
DpkiNotInstalled,
#[error("The agent {0} could not be found in DPKI")]
DpkiAgentMissing(AgentPubKey),
#[error("The agent {0} was found to be invalid at {1} according to the DPKI service")]
DpkiAgentInvalid(AgentPubKey, Timestamp),
}
pub type DpkiServiceResult<T> = Result<T, DpkiServiceError>;