ic_memory/runtime/
adoption.rs1use super::{MemoryRuntime, RuntimeLifecycle, RuntimeOpenError};
2use crate::{SealedDeclarationSnapshot, StableKey};
3use ic_stable_structures::Memory;
4
5#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
14#[non_exhaustive]
15pub enum RuntimeAdoptionError {
16 #[error(transparent)]
18 Open(#[from] RuntimeOpenError),
19 #[error("no allocation requirements declared by authority '{authority}'")]
21 UnknownAuthority { authority: String },
22 #[error(
24 "stable key '{stable_key}' is committed under '{committed_authority}', not '{requested_authority}'"
25 )]
26 AuthorityMismatch {
27 stable_key: String,
28 committed_authority: String,
29 requested_authority: String,
30 },
31}
32
33impl<M: Memory> MemoryRuntime<M> {
34 pub fn verify_authority(
43 &self,
44 requirements: &SealedDeclarationSnapshot,
45 authority: &str,
46 ) -> Result<(), RuntimeAdoptionError> {
47 let RuntimeLifecycle::Bootstrapped {
48 binding,
49 committed_allocations,
50 } = &self.lifecycle
51 else {
52 return Err(RuntimeOpenError::NotBootstrapped.into());
53 };
54 let mut found = false;
55 for request in requirements.requests() {
56 if request.authority() == authority {
57 found = true;
58 verify_requirement(
59 committed_allocations,
60 &binding.pool,
61 authority,
62 request.stable_key(),
63 )?;
64 }
65 }
66 if !found {
67 return Err(RuntimeAdoptionError::UnknownAuthority {
68 authority: authority.to_string(),
69 });
70 }
71 Ok(())
72 }
73}
74
75fn verify_requirement(
76 committed: &crate::CommittedAllocations,
77 pool: &crate::MemoryAllocationPool,
78 authority: &str,
79 key: &StableKey,
80) -> Result<(), RuntimeAdoptionError> {
81 crate::capability::declaration_for_key(committed.declarations(), key.as_str())
82 .ok_or_else(|| RuntimeOpenError::StableKeyNotCommitted(key.to_string()))?;
83 let admitted_authority = pool
84 .authority_for_key(key)
85 .expect("committed key has an admitted owner");
86 if admitted_authority != authority {
87 return Err(RuntimeAdoptionError::AuthorityMismatch {
88 stable_key: key.to_string(),
89 committed_authority: admitted_authority.to_string(),
90 requested_authority: authority.to_string(),
91 });
92 }
93 Ok(())
94}