use crate::{
InternalError,
domain::policy::topology::TopologyPolicy,
ops::{
storage::{
directory::{app::AppDirectoryOps, subnet::SubnetDirectoryOps},
registry::subnet::SubnetRegistryOps,
},
topology::policy::mapper::RegistryPolicyInputMapper,
},
workflow::{
cascade::{state::StateCascadeWorkflow, topology::TopologyCascadeWorkflow},
ic::provision::ProvisionWorkflow,
prelude::*,
},
};
pub struct PropagationWorkflow;
impl PropagationWorkflow {
pub async fn propagate_topology(target: Principal) -> Result<(), InternalError> {
TopologyCascadeWorkflow::root_cascade_topology_for_pid(target).await
}
pub async fn propagate_state(
target: Principal,
role: &CanisterRole,
) -> Result<(), InternalError> {
if role.is_wasm_store() {
return Ok(());
}
let snapshot = ProvisionWorkflow::rebuild_directories_from_registry(Some(role))?
.with_app_state()
.with_subnet_state()
.build();
StateCascadeWorkflow::root_cascade_state_for_pid(target, &snapshot).await?;
let registry_data = SubnetRegistryOps::data();
let registry_input = RegistryPolicyInputMapper::record_to_policy_input(registry_data);
let app_data = AppDirectoryOps::data();
let subnet_data = SubnetDirectoryOps::data();
TopologyPolicy::assert_directory_consistent_with_registry(
®istry_input,
&app_data.entries,
)
.map_err(InternalError::from)?;
TopologyPolicy::assert_directory_consistent_with_registry(
®istry_input,
&subnet_data.entries,
)
.map_err(InternalError::from)?;
Ok(())
}
}