use crate::{
InternalError,
domain::policy::pure::topology::IndexPolicyInput,
dto::topology::SubnetIndexArgs,
ops::{
config::ConfigOps,
prelude::*,
storage::index::{
ensure_allowed_roles, ensure_required_roles, ensure_unique_roles,
mapper::{IndexEntryMapper, SubnetIndexDataMapper},
},
},
storage::stable::index::subnet::{SubnetIndex, SubnetIndexData},
view::topology::IndexEntryView,
};
pub struct SubnetIndexOps;
impl SubnetIndexOps {
#[must_use]
pub fn get(role: &CanisterRole) -> Option<Principal> {
SubnetIndex::export()
.entries
.iter()
.find_map(|entry| (&entry.role == role).then_some(entry.pid))
}
#[must_use]
pub(crate) fn data() -> SubnetIndexData {
SubnetIndex::export()
}
#[must_use]
pub fn entry_projections() -> Vec<IndexEntryView> {
IndexEntryMapper::records_to_projections(SubnetIndex::export().entries)
}
#[must_use]
pub(crate) fn policy_input() -> Vec<IndexPolicyInput> {
IndexEntryMapper::records_to_policy_input(&SubnetIndex::export().entries)
}
#[must_use]
pub fn snapshot_args() -> SubnetIndexArgs {
SubnetIndexDataMapper::data_to_input(SubnetIndex::export())
}
pub(crate) fn filter_args_for_local_config(
args: SubnetIndexArgs,
) -> Result<SubnetIndexArgs, InternalError> {
let allowed = ConfigOps::current_subnet()?.subnet_index_roles();
Ok(SubnetIndexArgs(
args.0
.into_iter()
.filter(|entry| allowed.contains(&entry.role))
.collect(),
))
}
pub(crate) fn import_args_allow_incomplete(args: SubnetIndexArgs) -> Result<(), InternalError> {
let data = SubnetIndexDataMapper::input_to_data(args);
ensure_unique_roles(&data.entries, "subnet")?;
let subnet_cfg = ConfigOps::current_subnet()?;
ensure_allowed_roles(&data.entries, "subnet", &subnet_cfg.subnet_index_roles())?;
SubnetIndex::import(data);
Ok(())
}
pub fn import(data: SubnetIndexData) -> Result<(), InternalError> {
ensure_unique_roles(&data.entries, "subnet")?;
let subnet_cfg = ConfigOps::current_subnet()?;
let required = subnet_cfg.subnet_index_roles();
ensure_allowed_roles(&data.entries, "subnet", &required)?;
ensure_required_roles(&data.entries, "subnet", &required)?;
SubnetIndex::import(data);
Ok(())
}
pub(crate) fn import_trusted_partial(data: SubnetIndexData) -> Result<(), InternalError> {
ensure_unique_roles(&data.entries, "subnet")?;
SubnetIndex::import(data);
Ok(())
}
}