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 allocations,
50 ..
51 } = &self.lifecycle
52 else {
53 return Err(RuntimeOpenError::NotBootstrapped.into());
54 };
55 let mut found = false;
56 for request in requirements.requests() {
57 if request.authority() == authority {
58 found = true;
59 verify_requirement(allocations, &binding.pool, authority, request.stable_key())?;
60 }
61 }
62 if !found {
63 return Err(RuntimeAdoptionError::UnknownAuthority {
64 authority: authority.to_string(),
65 });
66 }
67 Ok(())
68 }
69}
70
71fn verify_requirement(
72 committed: &[crate::AllocationDeclaration],
73 pool: &crate::MemoryAllocationPool,
74 authority: &str,
75 key: &StableKey,
76) -> Result<(), RuntimeAdoptionError> {
77 crate::declaration::declaration_for_key(committed, key.as_str())
78 .ok_or_else(|| RuntimeOpenError::StableKeyNotCommitted(key.to_string()))?;
79 let admitted_authority = pool
80 .authority_for_key(key)
81 .expect("committed key has an admitted owner");
82 if admitted_authority != authority {
83 return Err(RuntimeAdoptionError::AuthorityMismatch {
84 stable_key: key.to_string(),
85 committed_authority: admitted_authority.to_string(),
86 requested_authority: authority.to_string(),
87 });
88 }
89 Ok(())
90}