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