Skip to main content

canic_core/storage/stable/registry/
app.rs

1use crate::{
2    cdk::structures::{DefaultMemoryImpl, memory::VirtualMemory},
3    storage::{prelude::*, stable::memory::topology::APP_REGISTRY_ID},
4};
5use ic_memory::stable_structures::btreemap::BTreeMap as StableBtreeMap;
6use std::cell::RefCell;
7
8//
9// APP_REGISTRY
10// An application-wide map of every subnet principal to its
11// corresponding root principal
12//
13
14eager_static! {
15    static APP_REGISTRY: RefCell<StableBtreeMap<Principal, Principal, VirtualMemory<DefaultMemoryImpl>>> =
16        RefCell::new(StableBtreeMap::init(crate::ic_memory_key!("canic.core.app_registry.v1", AppRegistry, APP_REGISTRY_ID)));
17}
18
19///
20/// AppRegistryRecord
21///
22
23#[derive(Clone, Debug)]
24pub struct AppRegistryRecord {
25    pub entries: Vec<(Principal, Principal)>,
26}
27
28///
29/// AppRegistry
30///
31/// Stable-memory–backed model relation mapping subnet principals to their
32/// corresponding root principals.
33///
34/// This registry is authoritative and is populated via internal lifecycle
35/// operations. It is exported for snapshot/view construction but is not
36/// imported wholesale.
37///
38
39pub struct AppRegistry;
40
41impl AppRegistry {
42    /// Insert or replace the root principal recorded for a subnet.
43    pub(crate) fn upsert(subnet_pid: Principal, root_pid: Principal) {
44        APP_REGISTRY.with_borrow_mut(|map| {
45            map.insert(subnet_pid, root_pid);
46        });
47    }
48
49    #[must_use]
50    pub(crate) fn export() -> AppRegistryRecord {
51        AppRegistryRecord {
52            entries: APP_REGISTRY
53                .with_borrow(|map| map.iter().map(|e| (*e.key(), e.value())).collect()),
54        }
55    }
56}